From 1d9979fd0035485bc99b5c7297871bfe8e78c741 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Sat, 9 Nov 2024 12:18:31 -0500 Subject: [PATCH] feat(daily): november 8th's daily --- posts/algorithms/leetcode-daily.html | 187 +++++++++++++++++++++++++++ scripts/index.js | 1 + scripts/post.js | 1 + 3 files changed, 189 insertions(+) create mode 100644 posts/algorithms/leetcode-daily.html diff --git a/posts/algorithms/leetcode-daily.html b/posts/algorithms/leetcode-daily.html new file mode 100644 index 0000000..c0e53c7 --- /dev/null +++ b/posts/algorithms/leetcode-daily.html @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + Barrett Ruth + + +
+ +
+ barrett@ruth:~$ /algorithms + +
+
+
+
+
+
+

Leetcode Daily

+
+
+
+

+ minimum array end + — 9/11/24 +

+
+
+

problem statement

+

+ Given some \(x\) and \(n\), construct a strictly increasing array + (say + nums + ) of length \(n\) such that + nums[0] & nums[1] ... & nums[n - 1] == x + , where + & + denotes the bitwise AND operator. +

+

+ Finally, return the minimum possible value of + nums[n - 1]. +

+
+

understanding the problem

+

+ The main difficulty in this problem lies in understanding what is + being asked (intentionally or not, the phrasing is terrible). Some + initial notes: +

+
    +
  • The final array need not be constructed
  • +
  • + If the element-wise bitwise AND of an array equals + x if and only if each element has + x's bits set—and no other bit it set by + all elements +
  • +
  • + It makes sense to set nums[0] == x to ensure + nums[n - 1] is minimal +
  • +
+

developing an approach

+

+ An inductive approach is helpful. Consider the natural question: + “If I had correctly generated nums[:i]”, + how could I find nums[i]? In other words, + how can I find the next smallest number such that + nums + 's element-wise bitwise AND is still \(x\)? +

+

+ Hmm... this is tricky. Let's think of a similar problem to + glean some insight: “Given some \(x\), how can I find the next + smallest number?”. The answer is, of course, add one (bear + with me here). +

+

+ We also know that all of nums[i] must have at least + \(x\)'s bits set. Therefore, we need to alter the unset bits of + nums[i]. +

+

+ The key insight of this problem is combining these two ideas to + answer our question: + Just “add one” to nums[i - 1]'s + unset bits. Repeat this to find nums[n - 1]. +

+

+ One last piece is missing—how do we know the element-wise + bitwise AND is exactly \(x\)? Because + nums[i > 0] only sets \(x\)'s unset bits, every + number in nums will have at least \(x\)'s bits + set. Further, no other bits will be set because \(x\) has them + unset. +

+

carrying out the plan

+

Let's flesh out the remaining parts of the algorithm:

+
    +
  • + len(nums) == n and we initialize + nums[0] == x. So, we need to “add one” + n - 1 times +
  • +
  • + How do we carry out the additions? We could iterate \(n - 1\) + times and simulate them. However, we already know how we want to + alter the unset bits of nums[0] inductively— + (add one) and how many times we want to do this (\(n - + 1\)). Because we're adding one \(n-1\) times to \(x\)'s + unset bits (right to left, of course), we simply set its unset + bits to those of \(n - 1\). +
  • +
+

+ The implementation is relatively straightfoward. Traverse \(x\) from + least-to-most significant bit, setting its \(i\)th unset bit to \(n + - 1\)'s \(i\)th bit. Use a bitwise mask mask to + traverse \(x\). +

+
+
long long minEnd(int n, long long x) {
+    int bits_to_distribute = n - 1;
+    long long mask = 1;
+
+    while (bits_to_distribute > 0) {
+        if ((x & mask) == 0) {
+            // if the bit should be set, set it-otherwise, leave it alone
+            if ((bits_to_distribute & 1) == 1)
+                x |= mask;
+            bits_to_distribute >>= 1;
+        }
+        mask <<= 1;
+    }
+
+    return x;
+}
+
+

asymptotic complexity

+

+ Space Complexity: \(\Theta(1)\)—a constant amount of + numeric variables are allocated regardless of \(n\) and \(x\). +

+

+ Time Complexity: in the worst case, may need to traverse the + entirety of \(x\) to distribute every bit of \(n - 1\) to \(x\). + This occurs if and only if \(x\) is all ones (\(\exists k\gt 0 : + 2^k-1=x\))). \(x\) and \(n\) have \(lg(x)\) and \(lg(n)\) bits + respectively, so the solution is \(O(lg(x) + lg(n))\in O(log(xn))\). + \(1\leq x,n\leq 1e8\), so this runtime is bounded by + \(O(log(1e8^2))=O(log(1e16))=O(16)\). +

+
+
+
+ + + + diff --git a/scripts/index.js b/scripts/index.js index 38b4cd6..23885b2 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -19,6 +19,7 @@ const postMapping = new Map([ [ "Algorithms", [ + { name: "leetcode daily", link: "leetcode-daily" }, { name: "extrema circular buffer", link: "extrema-circular-buffer" }, { name: "two pointers", link: "two-pointers" }, ], diff --git a/scripts/post.js b/scripts/post.js index ad45e64..bfe4d6c 100644 --- a/scripts/post.js +++ b/scripts/post.js @@ -34,6 +34,7 @@ const setStyle = (h) => { const mdHeading = document.createElement("span"); const header = tagToHeader.has(h.tagName) ? tagToHeader.get(h.tagName) : ""; mdHeading.textContent = `${header} `; + mdHeading.style.color = getTopicColor(urlToTopic()); h.prepend(mdHeading); };