From 1728bae2adf7a85cd2a3590d6a1c02a000c9b183 Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Tue, 12 Nov 2024 11:46:16 -0500 Subject: [PATCH] feat: daily today --- posts/algorithms/leetcode-daily.html | 118 ++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/posts/algorithms/leetcode-daily.html b/posts/algorithms/leetcode-daily.html index 6c70b00..e828c32 100644 --- a/posts/algorithms/leetcode-daily.html +++ b/posts/algorithms/leetcode-daily.html @@ -38,6 +38,120 @@

Leetcode Daily

+
+

+ most beautiful item for each query + — 9/12/24 +

+
+
+

problem statement

+

+ Given an array items of \((price, beauty)\) tuples, + answer each integer query of \(queries\). The answer to some + query[i] is the maximum beauty of an item with + \(price\leq\)items[i][0]. +

+

understanding the problem

+

+ Focus on one aspect of the problem at a time. To answer a query, + we need to have considered: +

+
    +
  1. Items with a non-greater price
  2. +
  3. The beauty of all such items
  4. +
+

+ Given some query, how can we efficiently identify the + “last” item with an acceptable price? Leverage the + most common pre-processing algorithm: sorting. Subsequently, we + can binary search items (keyed by price, of course) + to identify all considerable items in \(O(lg(n))\). +

+

+ Great. Now we need to find the item with the largest beauty. + Naïvely considering all the element is a + correct approach—but is it correct? Considering our + binary search \(O(lg(n))\) and beauty search \(O(n)\) across + \(\Theta(n)\) queries with + len(items)<=len(queries)\(\leq10^5\), an + \(O(n^2lg(n))\) approach is certainly unacceptable. +

+

+ 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? +

+

+ 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 queries and + items with a linear scan will take \(O(nlg(n))\) + time, meeting the constraints. +

+
+

fleshing out the approach

+

+ A few specifics need to be understood before coding up the approach: +

+ +

+ carrying out the plan +

+
+
vector maximumBeauty(vector>& items, vector& 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 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);
+