feat(daily): november 8th's daily
This commit is contained in:
parent
872ce457f2
commit
1d9979fd00
3 changed files with 189 additions and 0 deletions
187
posts/algorithms/leetcode-daily.html
Normal file
187
posts/algorithms/leetcode-daily.html
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<link rel="stylesheet" href="/styles/common.css" />
|
||||||
|
<link rel="stylesheet" href="/styles/post.css" />
|
||||||
|
<link rel="icon" type="image/webp" href="/public/logo.webp" />
|
||||||
|
<link href="/public/prism/prism.css" rel="stylesheet" />
|
||||||
|
<link href="/public/prism/prism-theme.css" rel="stylesheet" />
|
||||||
|
<script defer src="/public/prism/prism.js"></script>
|
||||||
|
<link rel="stylesheet" href="/public/katex/katex.css" />
|
||||||
|
<script defer src="/public/katex/katex.js"></script>
|
||||||
|
<script
|
||||||
|
defer
|
||||||
|
src="/public/katex/katex-render.js"
|
||||||
|
onload="renderMathInElement(document.body);"
|
||||||
|
></script>
|
||||||
|
<title>Barrett Ruth</title>
|
||||||
|
</head>
|
||||||
|
<body class="graph-background">
|
||||||
|
<header>
|
||||||
|
<a
|
||||||
|
href="/"
|
||||||
|
style="text-decoration: none; color: inherit"
|
||||||
|
onclick="goHome(event)"
|
||||||
|
>
|
||||||
|
<div class="terminal-container">
|
||||||
|
<span class="terminal-prompt">barrett@ruth:~$ /algorithms</span>
|
||||||
|
<span class="terminal-cursor"></span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</header>
|
||||||
|
<main class="main">
|
||||||
|
<div class="post-container">
|
||||||
|
<header class="post-header">
|
||||||
|
<h1 class="post-title">Leetcode Daily</h1>
|
||||||
|
</header>
|
||||||
|
<article class="post-article">
|
||||||
|
<div class="fold">
|
||||||
|
<h2>
|
||||||
|
<a
|
||||||
|
target="blank"
|
||||||
|
href="https://leetcode.com/problems/minimum-array-end/"
|
||||||
|
>minimum array end</a
|
||||||
|
>
|
||||||
|
— 9/11/24
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="problem-content">
|
||||||
|
<h3>problem statement</h3>
|
||||||
|
<p>
|
||||||
|
Given some \(x\) and \(n\), construct a strictly increasing array
|
||||||
|
(say
|
||||||
|
<code>nums</code>
|
||||||
|
) of length \(n\) such that
|
||||||
|
<code>nums[0] & nums[1] ... & nums[n - 1] == x</code>
|
||||||
|
, where
|
||||||
|
<code>&</code>
|
||||||
|
denotes the bitwise AND operator.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Finally, return the minimum possible value of
|
||||||
|
<code>nums[n - 1]</code>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<h3>understanding the problem</h3>
|
||||||
|
<p>
|
||||||
|
The main difficulty in this problem lies in understanding what is
|
||||||
|
being asked (intentionally or not, the phrasing is terrible). Some
|
||||||
|
initial notes:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>The final array need not be constructed</li>
|
||||||
|
<li>
|
||||||
|
If the element-wise bitwise AND of an array equals
|
||||||
|
<code>x</code> if and only if each element has
|
||||||
|
<code>x</code>'s bits set—and no other bit it set by
|
||||||
|
all elements
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
It makes sense to set <code>nums[0] == x</code> to ensure
|
||||||
|
<code>nums[n - 1]</code> is minimal
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>developing an approach</h3>
|
||||||
|
<p>
|
||||||
|
An inductive approach is helpful. Consider the natural question:
|
||||||
|
“If I had correctly generated <code>nums[:i]</code>”,
|
||||||
|
how could I find <code>nums[i]</code>? In other words,
|
||||||
|
<i
|
||||||
|
>how can I find the next smallest number such that
|
||||||
|
<code>nums</code>
|
||||||
|
's element-wise bitwise AND is still \(x\)?</i
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
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).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We also know that all of <code>nums[i]</code> must have at least
|
||||||
|
\(x\)'s bits set. Therefore, we need to alter the unset bits of
|
||||||
|
<code>nums[i]</code>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The key insight of this problem is combining these two ideas to
|
||||||
|
answer our question:
|
||||||
|
<i
|
||||||
|
>Just “add one” to <code>nums[i - 1]</code>'s
|
||||||
|
unset bits</i
|
||||||
|
>. Repeat this to find <code>nums[n - 1]</code>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
One last piece is missing—how do we know the element-wise
|
||||||
|
bitwise AND is <i>exactly</i> \(x\)? Because
|
||||||
|
<code>nums[i > 0]</code> only sets \(x\)'s unset bits, every
|
||||||
|
number in <code>nums</code> will have at least \(x\)'s bits
|
||||||
|
set. Further, no other bits will be set because \(x\) has them
|
||||||
|
unset.
|
||||||
|
</p>
|
||||||
|
<h3>carrying out the plan</h3>
|
||||||
|
<p>Let's flesh out the remaining parts of the algorithm:</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<code>len(nums) == n</code> and we initialize
|
||||||
|
<code>nums[0] == x</code>. So, we need to “add one”
|
||||||
|
<code>n - 1</code> times
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
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 <code>nums[0]</code> inductively—
|
||||||
|
(add one) <i>and</i> 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\).
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
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 <code>mask</code> to
|
||||||
|
traverse \(x\).
|
||||||
|
</p>
|
||||||
|
<div class="post-code">
|
||||||
|
<pre><code class="language-cpp">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;
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
<h3>asymptotic complexity</h3>
|
||||||
|
<p>
|
||||||
|
<u>Space Complexity</u>: \(\Theta(1)\)—a constant amount of
|
||||||
|
numeric variables are allocated regardless of \(n\) and \(x\).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<u>Time Complexity</u>: 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)\).
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<script src="/scripts/common.js"></script>
|
||||||
|
<script src="/scripts/post.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -19,6 +19,7 @@ const postMapping = new Map([
|
||||||
[
|
[
|
||||||
"Algorithms",
|
"Algorithms",
|
||||||
[
|
[
|
||||||
|
{ name: "leetcode daily", link: "leetcode-daily" },
|
||||||
{ name: "extrema circular buffer", link: "extrema-circular-buffer" },
|
{ name: "extrema circular buffer", link: "extrema-circular-buffer" },
|
||||||
{ name: "two pointers", link: "two-pointers" },
|
{ name: "two pointers", link: "two-pointers" },
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ const setStyle = (h) => {
|
||||||
const mdHeading = document.createElement("span");
|
const mdHeading = document.createElement("span");
|
||||||
const header = tagToHeader.has(h.tagName) ? tagToHeader.get(h.tagName) : "";
|
const header = tagToHeader.has(h.tagName) ? tagToHeader.get(h.tagName) : "";
|
||||||
mdHeading.textContent = `${header} `;
|
mdHeading.textContent = `${header} `;
|
||||||
|
mdHeading.style.color = getTopicColor(urlToTopic());
|
||||||
h.prepend(mdHeading);
|
h.prepend(mdHeading);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue