feat: daily today
This commit is contained in:
parent
07e4afc62b
commit
1728bae2ad
1 changed files with 117 additions and 1 deletions
|
|
@ -38,6 +38,120 @@
|
||||||
<h1 class="post-title">Leetcode Daily</h1>
|
<h1 class="post-title">Leetcode Daily</h1>
|
||||||
</header>
|
</header>
|
||||||
<article class="post-article">
|
<article class="post-article">
|
||||||
|
<div class="fold">
|
||||||
|
<h2>
|
||||||
|
<a
|
||||||
|
target="blank"
|
||||||
|
href="https://leetcode.com/problems/most-beautiful-item-for-each-query/description/"
|
||||||
|
>most beautiful item for each query</a
|
||||||
|
>
|
||||||
|
— 9/12/24
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="problem-content">
|
||||||
|
<h3>problem statement</h3>
|
||||||
|
<p>
|
||||||
|
Given an array <code>items</code> of \((price, beauty)\) tuples,
|
||||||
|
answer each integer query of \(queries\). The answer to some
|
||||||
|
<code>query[i]</code> is the maximum beauty of an item with
|
||||||
|
\(price\leq\)<code>items[i][0]</code>.
|
||||||
|
</p>
|
||||||
|
<h3>understanding the problem</h3>
|
||||||
|
<p>
|
||||||
|
Focus on one aspect of the problem at a time. To answer a query,
|
||||||
|
we need to have considered:
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li>Items with a non-greater price</li>
|
||||||
|
<li>The beauty of all such items</li>
|
||||||
|
</ol>
|
||||||
|
<p>
|
||||||
|
Given some query, how can we <i>efficiently</i> identify the
|
||||||
|
“last” item with an acceptable price? Leverage the
|
||||||
|
most common pre-processing algorithm: sorting. Subsequently, we
|
||||||
|
can binary search <code>items</code> (keyed by price, of course)
|
||||||
|
to identify all considerable items in \(O(lg(n))\).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Great. Now we need to find the item with the largest beauty.
|
||||||
|
Naïvely considering all the element is a
|
||||||
|
<i>correct</i> approach—but is it correct? Considering our
|
||||||
|
binary search \(O(lg(n))\) and beauty search \(O(n)\) across
|
||||||
|
\(\Theta(n)\) queries with
|
||||||
|
<code>len(items)<=len(queries)</code>\(\leq10^5\), an
|
||||||
|
\(O(n^2lg(n))\) approach is certainly unacceptable.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Consider alternative approaches to responding to our queries. It
|
||||||
|
is clear that answering them in-order yields no benefit (i.e. we
|
||||||
|
have to consider each item all over again, per query)—could
|
||||||
|
we answer them in another order to save computations?
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Visualizing our items from left-to-right, we's interested in
|
||||||
|
both increasing beauty and prices. If we can scan our items left
|
||||||
|
to right, we can certainly “accumulate” a running
|
||||||
|
maximal beauty. We can leverage sorting once again to answer our
|
||||||
|
queries left-to-right, then re-order them appropriately before
|
||||||
|
returning a final answer. Sorting both <code>queries</code> and
|
||||||
|
<code>items</code> with a linear scan will take \(O(nlg(n))\)
|
||||||
|
time, meeting the constraints.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<h3>fleshing out the approach</h3>
|
||||||
|
<p>
|
||||||
|
A few specifics need to be understood before coding up the approach:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Re-ordering the queries: couple <code>query[i]</code> with
|
||||||
|
<code>i</code>, then sort. When responding to queries in sorted
|
||||||
|
order, we know where to place them in an output
|
||||||
|
container—index <code>i</code>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
The linear scan: accumulate a running maximal beauty, starting at
|
||||||
|
index <code>0</code>. For some query <code>query</code>, we want
|
||||||
|
to consider all items with price less than or equal to
|
||||||
|
<code>query</code>. Therefore, loop until this condition is
|
||||||
|
<i>violated</i>— the previous index will represent the last
|
||||||
|
considered item.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Edge cases: it's perfectly possible the last considered item
|
||||||
|
is invalid (consider a query cheaper than the cheapest item).
|
||||||
|
Return <code>0</code> as specified by the problem constraints.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>
|
||||||
|
carrying out the plan
|
||||||
|
</h3>
|
||||||
|
<div class="post-code">
|
||||||
|
<pre><code class="language-cpp">vector<int> maximumBeauty(vector<vector<int>>& items, vector<int>& queries) {
|
||||||
|
std::sort(items.begin(), items.end());
|
||||||
|
std::vector<pair<int, int>> sorted_queries;
|
||||||
|
sorted_queries.reserve(queries.size());
|
||||||
|
// couple queries with their indices
|
||||||
|
for (size_t i = 0; i < queries.size(); ++i) {
|
||||||
|
sorted_queries.emplace_back(queries[i], i);
|
||||||
|
}
|
||||||
|
std::sort(sorted_queries.begin(), sorted_queries.end());
|
||||||
|
|
||||||
|
int beauty = items[0][1];
|
||||||
|
size_t i = 0;
|
||||||
|
std::vector<int> ans(queries.size());
|
||||||
|
|
||||||
|
for (const auto [query, index] : sorted_queries) {
|
||||||
|
while (i < items.size() && items[i][0] <= query) {
|
||||||
|
beauty = std::max(beauty, items[i][1]);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
// invariant: items[i - 1] is the rightmost considerable item
|
||||||
|
ans[index] = i > 0 && items[i - 1][0] <= query ? beauty : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(ans);</code></pre>
|
||||||
|
</div>
|
||||||
<div class="fold">
|
<div class="fold">
|
||||||
<h2>
|
<h2>
|
||||||
<a
|
<a
|
||||||
|
|
@ -210,7 +324,9 @@
|
||||||
Note that the size of the frequency map is bounded by
|
Note that the size of the frequency map is bounded by
|
||||||
\(lg_{2}({10^9})\approx30\).
|
\(lg_{2}({10^9})\approx30\).
|
||||||
</p>
|
</p>
|
||||||
<p><u>Space Complexity</u>: Thus, the window uses \(O(1)\) space.</p>
|
<p>
|
||||||
|
<u>Space Complexity</u>: Thus, the window uses \(O(1)\) space.
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<u>Time Complexity</u>: \(\Theta(\)<code>len(nums)</code>\()\)
|
<u>Time Complexity</u>: \(\Theta(\)<code>len(nums)</code>\()\)
|
||||||
—every element of <code>nums</code> is considered at least
|
—every element of <code>nums</code> is considered at least
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue