From feb47d608aa9ea7b63c158726b4ee152f901710a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=BE=D1=80=D0=B5=D0=B2=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80?= Date: Mon, 26 Feb 2024 12:23:03 +0300 Subject: [PATCH] Earliest Second to Mark Indices I --- CMakeLists.txt | 1 + PROBLEM_LIST.md | 1 + .../CMakeLists.txt | 1 + .../solution.hpp | 47 +++++++++++++++++++ .../test.cpp | 35 ++++++++++++++ 5 files changed, 85 insertions(+) create mode 100644 solutions/earliest-second-to-mark-indices-i/CMakeLists.txt create mode 100644 solutions/earliest-second-to-mark-indices-i/solution.hpp create mode 100644 solutions/earliest-second-to-mark-indices-i/test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fb699263..8316cbec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -417,6 +417,7 @@ add_task(double-modular-exponentiation) add_task(dungeon-game) add_task(duplicate-zeros) add_task(earliest-possible-day-of-full-bloom) +add_task(earliest-second-to-mark-indices-i) add_task(edit-distance) add_task(egg-drop-with-2-eggs-and-n-floors) add_task(element-appearing-more-than-25-in-sorted-array) diff --git a/PROBLEM_LIST.md b/PROBLEM_LIST.md index 2f31cc5d..dc592578 100644 --- a/PROBLEM_LIST.md +++ b/PROBLEM_LIST.md @@ -1891,3 +1891,4 @@ | 3044. | [Most Frequent Prime](https://leetcode.com/problems/most-frequent-prime/) | [C++](./solutions/most-frequent-prime/solution.hpp) | | O(N2M2K0.5) / O(1)| | | | 3046. | [Split the Array](https://leetcode.com/problems/split-the-array/) | [C++](./solutions/split-the-array/solution.hpp) | | O(N) / O(N)| | | | 3047. | [Find the Largest Area of Square Inside Two Rectangles](https://leetcode.com/problems/find-the-largest-area-of-square-inside-two-rectangles/) | [C++](./solutions/find-the-largest-area-of-square-inside-two-rectangles/solution.hpp) | | O(N2) / O(1)| | | +| 3048. | [Earliest Second to Mark Indices I](https://leetcode.com/problems/earliest-second-to-mark-indices-i/) | [C++](./solutions/earliest-second-to-mark-indices-i/solution.hpp) | | O((M+N)logM) / O(N)| | | diff --git a/solutions/earliest-second-to-mark-indices-i/CMakeLists.txt b/solutions/earliest-second-to-mark-indices-i/CMakeLists.txt new file mode 100644 index 00000000..dec93621 --- /dev/null +++ b/solutions/earliest-second-to-mark-indices-i/CMakeLists.txt @@ -0,0 +1 @@ +add_catch(test_earliest_second_to_mark_indices_i test.cpp) diff --git a/solutions/earliest-second-to-mark-indices-i/solution.hpp b/solutions/earliest-second-to-mark-indices-i/solution.hpp new file mode 100644 index 00000000..0bec23e3 --- /dev/null +++ b/solutions/earliest-second-to-mark-indices-i/solution.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include + +// Time: O((M+N)logM) +// Space: O(N) + +class Solution { +public: + static int + earliestSecondToMarkIndices(const std::vector &nums, + const std::vector &changeIndices) { + const int m = changeIndices.size(); + int left = 1, right = m + 1; + while (left < right) { + const auto middle = left + (right - left) / 2; + canMark(nums, changeIndices, middle) ? right = middle : left = middle + 1; + } + return left == m + 1 ? -1 : left; + } + +private: + static bool canMark(const std::vector &nums, + const std::vector &changeIndices, int m) { + std::vector last(nums.size(), -1); + for (int i = 0; i < m; ++i) { + last[changeIndices[i] - 1] = i; + } + + if (std::ranges::any_of(last, [](int a) { return a == -1; })) { + return false; + } + + int ops = 0; + for (int i = 0; i < m; ++i) { + if (i == last[changeIndices[i] - 1]) { + if (ops < nums[changeIndices[i] - 1]) { + return false; + } + ops -= nums[changeIndices[i] - 1]; + } else { + ++ops; + } + } + return true; + } +}; diff --git a/solutions/earliest-second-to-mark-indices-i/test.cpp b/solutions/earliest-second-to-mark-indices-i/test.cpp new file mode 100644 index 00000000..af804c28 --- /dev/null +++ b/solutions/earliest-second-to-mark-indices-i/test.cpp @@ -0,0 +1,35 @@ +#include + +#include + +TEST_CASE("Simple") { + struct TestCase { + std::vector nums; + std::vector changeIndices; + int expected; + }; + + std::vector test_cases{ + { + .nums{1, 3}, + .changeIndices{1, 1, 1, 2, 1, 1, 1}, + .expected = 6, + }, + { + .nums{2, 2, 0}, + .changeIndices{2, 2, 2, 2, 3, 2, 2, 1}, + .expected = 8, + }, + { + .nums{0, 1}, + .changeIndices{2, 2, 2}, + .expected = -1, + }, + }; + + for (const auto &[nums, changeIndices, expected] : test_cases) { + const auto actual = + Solution::earliestSecondToMarkIndices(nums, changeIndices); + REQUIRE(expected == actual); + } +}