diff --git a/solution/2800-2899/2823.Deep Object Filter/README_EN.md b/solution/2800-2899/2823.Deep Object Filter/README_EN.md index 97c7c507a591f..cefde933e74fb 100644 --- a/solution/2800-2899/2823.Deep Object Filter/README_EN.md +++ b/solution/2800-2899/2823.Deep Object Filter/README_EN.md @@ -55,7 +55,7 @@ fn = (x) => Array.isArray(x) <ul> <li><code>fn</code> is a function that returns a boolean value</li> <li><code>obj</code> is a valid JSON object</li> - <li><code>2 <= JSON.stringify(obj).length <= 10**5</code></li> + <li><code>2 <= JSON.stringify(obj).length <= 10<sup>5</sup></code></li> </ul> ## Solutions diff --git a/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/README.md b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/README.md new file mode 100644 index 0000000000000..ffc9ded1ca73d --- /dev/null +++ b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/README.md @@ -0,0 +1,175 @@ +# [2824. 统计和小于目标的下标对数目](https://leetcode.cn/problems/count-pairs-whose-sum-is-less-than-target) + +[English Version](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +给你一个下标从 <strong>0</strong> 开始长度为 <code>n</code> 的整数数组 <code>nums</code> 和一个整数 <code>target</code> ,请你返回满足 <code>0 <= i < j < n</code> 且 <code>nums[i] + nums[j] < target</code> 的下标对 <code>(i, j)</code> 的数目。 + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<b>输入:</b>nums = [-1,1,2,3,1], target = 2 +<b>输出:</b>3 +<b>解释:</b>总共有 3 个下标对满足题目描述: +- (0, 1) ,0 < 1 且 nums[0] + nums[1] = 0 < target +- (0, 2) ,0 < 2 且 nums[0] + nums[2] = 1 < target +- (0, 4) ,0 < 4 且 nums[0] + nums[4] = 0 < target +注意 (0, 3) 不计入答案因为 nums[0] + nums[3] 不是严格小于 target 。 +</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<b>输入:</b>nums = [-6,2,5,-2,-7,-1,3], target = -2 +<b>输出:</b>10 +<b>解释:</b>总共有 10 个下标对满足题目描述: +- (0, 1) ,0 < 1 且 nums[0] + nums[1] = -4 < target +- (0, 3) ,0 < 3 且 nums[0] + nums[3] = -8 < target +- (0, 4) ,0 < 4 且 nums[0] + nums[4] = -13 < target +- (0, 5) ,0 < 5 且 nums[0] + nums[5] = -7 < target +- (0, 6) ,0 < 6 且 nums[0] + nums[6] = -3 < target +- (1, 4) ,1 < 4 且 nums[1] + nums[4] = -5 < target +- (3, 4) ,3 < 4 且 nums[3] + nums[4] = -9 < target +- (3, 5) ,3 < 5 且 nums[3] + nums[5] = -3 < target +- (4, 5) ,4 < 5 且 nums[4] + nums[5] = -8 < target +- (4, 6) ,4 < 6 且 nums[4] + nums[6] = -4 < target +</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>1 <= nums.length == n <= 50</code></li> + <li><code>-50 <= nums[i], target <= 50</code></li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:排序 + 二分查找** + +我们先对数组 $nums$ 进行排序,然后枚举 $j$,在 $[0, j)$ 的范围内使用二分查找第一个大于等于 $target - nums[j]$ 的下标 $i$,那么 $[0, i)$ 的范围内的所有下标 $k$ 都满足条件,因此答案增加 $i$。 + +遍历结束后,我们返回答案。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是数组 $nums$ 的长度。 + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def countPairs(self, nums: List[int], target: int) -> int: + nums.sort() + ans = 0 + for j, x in enumerate(nums): + i = bisect_left(nums, target - x, hi=j) + ans += i + return ans +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + public int countPairs(List<Integer> nums, int target) { + Collections.sort(nums); + int ans = 0; + for (int j = 0; j < nums.size(); ++j) { + int x = nums.get(j); + int i = search(nums, target - x, j); + ans += i; + } + return ans; + } + + private int search(List<Integer> nums, int x, int r) { + int l = 0; + while (l < r) { + int mid = (l + r) >> 1; + if (nums.get(mid) >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int countPairs(vector<int>& nums, int target) { + sort(nums.begin(), nums.end()); + int ans = 0; + for (int j = 0; j < nums.size(); ++j) { + int i = lower_bound(nums.begin(), nums.begin() + j, target - nums[j]) - nums.begin(); + ans += i; + } + return ans; + } +}; +``` + +### **Go** + +```go +func countPairs(nums []int, target int) (ans int) { + sort.Ints(nums) + for j, x := range nums { + i := sort.SearchInts(nums[:j], target-x) + ans += i + } + return +} +``` + +### **TypeScript** + +```ts +function countPairs(nums: number[], target: number): number { + nums.sort((a, b) => a - b); + let ans = 0; + const search = (x: number, r: number): number => { + let l = 0; + while (l < r) { + const mid = (l + r) >> 1; + if (nums[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + for (let j = 0; j < nums.length; ++j) { + const i = search(target - nums[j], j); + ans += i; + } + return ans; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/README_EN.md b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/README_EN.md new file mode 100644 index 0000000000000..1c3d3d9d905f5 --- /dev/null +++ b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/README_EN.md @@ -0,0 +1,157 @@ +# [2824. Count Pairs Whose Sum is Less than Target](https://leetcode.com/problems/count-pairs-whose-sum-is-less-than-target) + +[中文文档](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README.md) + +## Description + +Given a <strong>0-indexed</strong> integer array <code>nums</code> of length <code>n</code> and an integer <code>target</code>, return <em>the number of pairs</em> <code>(i, j)</code> <em>where</em> <code>0 <= i < j < n</code> <em>and</em> <code>nums[i] + nums[j] < target</code>. + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> nums = [-1,1,2,3,1], target = 2 +<strong>Output:</strong> 3 +<strong>Explanation:</strong> There are 3 pairs of indices that satisfy the conditions in the statement: +- (0, 1) since 0 < 1 and nums[0] + nums[1] = 0 < target +- (0, 2) since 0 < 2 and nums[0] + nums[2] = 1 < target +- (0, 4) since 0 < 4 and nums[0] + nums[4] = 0 < target +Note that (0, 3) is not counted since nums[0] + nums[3] is not strictly less than the target. +</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> nums = [-6,2,5,-2,-7,-1,3], target = -2 +<strong>Output:</strong> 10 +<strong>Explanation:</strong> There are 10 pairs of indices that satisfy the conditions in the statement: +- (0, 1) since 0 < 1 and nums[0] + nums[1] = -4 < target +- (0, 3) since 0 < 3 and nums[0] + nums[3] = -8 < target +- (0, 4) since 0 < 4 and nums[0] + nums[4] = -13 < target +- (0, 5) since 0 < 5 and nums[0] + nums[5] = -7 < target +- (0, 6) since 0 < 6 and nums[0] + nums[6] = -3 < target +- (1, 4) since 1 < 4 and nums[1] + nums[4] = -5 < target +- (3, 4) since 3 < 4 and nums[3] + nums[4] = -9 < target +- (3, 5) since 3 < 5 and nums[3] + nums[5] = -3 < target +- (4, 5) since 4 < 5 and nums[4] + nums[5] = -8 < target +- (4, 6) since 4 < 6 and nums[4] + nums[6] = -4 < target +</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>1 <= nums.length == n <= 50</code></li> + <li><code>-50 <= nums[i], target <= 50</code></li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def countPairs(self, nums: List[int], target: int) -> int: + nums.sort() + ans = 0 + for j, x in enumerate(nums): + i = bisect_left(nums, target - x, hi=j) + ans += i + return ans +``` + +### **Java** + +```java +class Solution { + public int countPairs(List<Integer> nums, int target) { + Collections.sort(nums); + int ans = 0; + for (int j = 0; j < nums.size(); ++j) { + int x = nums.get(j); + int i = search(nums, target - x, j); + ans += i; + } + return ans; + } + + private int search(List<Integer> nums, int x, int r) { + int l = 0; + while (l < r) { + int mid = (l + r) >> 1; + if (nums.get(mid) >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int countPairs(vector<int>& nums, int target) { + sort(nums.begin(), nums.end()); + int ans = 0; + for (int j = 0; j < nums.size(); ++j) { + int i = lower_bound(nums.begin(), nums.begin() + j, target - nums[j]) - nums.begin(); + ans += i; + } + return ans; + } +}; +``` + +### **Go** + +```go +func countPairs(nums []int, target int) (ans int) { + sort.Ints(nums) + for j, x := range nums { + i := sort.SearchInts(nums[:j], target-x) + ans += i + } + return +} +``` + +### **TypeScript** + +```ts +function countPairs(nums: number[], target: number): number { + nums.sort((a, b) => a - b); + let ans = 0; + const search = (x: number, r: number): number => { + let l = 0; + while (l < r) { + const mid = (l + r) >> 1; + if (nums[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + for (let j = 0; j < nums.length; ++j) { + const i = search(target - nums[j], j); + ans += i; + } + return ans; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.cpp b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.cpp new file mode 100644 index 0000000000000..8b5f0588f7e79 --- /dev/null +++ b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.cpp @@ -0,0 +1,12 @@ +class Solution { +public: + int countPairs(vector<int>& nums, int target) { + sort(nums.begin(), nums.end()); + int ans = 0; + for (int j = 0; j < nums.size(); ++j) { + int i = lower_bound(nums.begin(), nums.begin() + j, target - nums[j]) - nums.begin(); + ans += i; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.go b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.go new file mode 100644 index 0000000000000..8b1ed608a1819 --- /dev/null +++ b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.go @@ -0,0 +1,8 @@ +func countPairs(nums []int, target int) (ans int) { + sort.Ints(nums) + for j, x := range nums { + i := sort.SearchInts(nums[:j], target-x) + ans += i + } + return +} \ No newline at end of file diff --git a/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.java b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.java new file mode 100644 index 0000000000000..4467b78eb1cf8 --- /dev/null +++ b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.java @@ -0,0 +1,25 @@ +class Solution { + public int countPairs(List<Integer> nums, int target) { + Collections.sort(nums); + int ans = 0; + for (int j = 0; j < nums.size(); ++j) { + int x = nums.get(j); + int i = search(nums, target - x, j); + ans += i; + } + return ans; + } + + private int search(List<Integer> nums, int x, int r) { + int l = 0; + while (l < r) { + int mid = (l + r) >> 1; + if (nums.get(mid) >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.py b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.py new file mode 100644 index 0000000000000..c7012315078ba --- /dev/null +++ b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.py @@ -0,0 +1,8 @@ +class Solution: + def countPairs(self, nums: List[int], target: int) -> int: + nums.sort() + ans = 0 + for j, x in enumerate(nums): + i = bisect_left(nums, target - x, hi=j) + ans += i + return ans diff --git a/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.ts b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.ts new file mode 100644 index 0000000000000..fd9fce8610d44 --- /dev/null +++ b/solution/2800-2899/2824.Count Pairs Whose Sum is Less than Target/Solution.ts @@ -0,0 +1,21 @@ +function countPairs(nums: number[], target: number): number { + nums.sort((a, b) => a - b); + let ans = 0; + const search = (x: number, r: number): number => { + let l = 0; + while (l < r) { + const mid = (l + r) >> 1; + if (nums[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + for (let j = 0; j < nums.length; ++j) { + const i = search(target - nums[j], j); + ans += i; + } + return ans; +} diff --git a/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/README.md b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/README.md new file mode 100644 index 0000000000000..331bd3c49072a --- /dev/null +++ b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/README.md @@ -0,0 +1,160 @@ +# [2825. 循环增长使字符串子序列等于另一个字符串](https://leetcode.cn/problems/make-string-a-subsequence-using-cyclic-increments) + +[English Version](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +<p>给你一个下标从 <strong>0</strong> 开始的字符串 <code>str1</code> 和 <code>str2</code> 。</p> + +<p>一次操作中,你选择 <code>str1</code> 中的若干下标。对于选中的每一个下标 <code>i</code> ,你将 <code>str1[i]</code> <strong>循环</strong> 递增,变成下一个字符。也就是说 <code>'a'</code> 变成 <code>'b'</code> ,<code>'b'</code> 变成 <code>'c'</code> ,以此类推,<code>'z'</code> 变成 <code>'a'</code> 。</p> + +<p>如果执行以上操作 <strong>至多一次</strong> ,可以让 <code>str2</code> 成为 <code>str1</code> 的子序列,请你返回 <code>true</code> ,否则返回 <code>false</code> 。</p> + +<p><b>注意:</b>一个字符串的子序列指的是从原字符串中删除一些(可以一个字符也不删)字符后,剩下字符按照原本先后顺序组成的新字符串。</p> + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<b>输入:</b>str1 = "abc", str2 = "ad" +<b>输出:</b>true +<b>解释:</b>选择 str1 中的下标 2 。 +将 str1[2] 循环递增,得到 'd' 。 +因此,str1 变成 "abd" 且 str2 现在是一个子序列。所以返回 true 。</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<b>输入:</b>str1 = "zc", str2 = "ad" +<b>输出:</b>true +<b>解释:</b>选择 str1 中的下标 0 和 1 。 +将 str1[0] 循环递增得到 'a' 。 +将 str1[1] 循环递增得到 'd' 。 +因此,str1 变成 "ad" 且 str2 现在是一个子序列。所以返回 true 。</pre> + +<p><strong class="example">示例 3:</strong></p> + +<pre> +<b>输入:</b>str1 = "ab", str2 = "d" +<b>输出:</b>false +<b>解释:</b>这个例子中,没法在执行一次操作的前提下,将 str2 变为 str1 的子序列。 +所以返回 false 。</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>1 <= str1.length <= 10<sup>5</sup></code></li> + <li><code>1 <= str2.length <= 10<sup>5</sup></code></li> + <li><code>str1</code> 和 <code>str2</code> 只包含小写英文字母。</li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:双指针** + +本题实际上需要我们判断一个字符串 $s$ 是否为另一个字符串 $t$ 的子序列,只不过字符之间可以不完全匹配,如果两个字符相同,或者一个字符是另一个字符的下一个字符,就可以匹配。 + +时间复杂度 $O(m + n)$,其中 $m$ 和 $n$ 分别是字符串 $str1$ 和 $str2$ 的长度。空间复杂度 $O(1)$。 + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def canMakeSubsequence(self, str1: str, str2: str) -> bool: + i = 0 + for c in str1: + d = "a" if c == "z" else chr(ord(c) + 1) + if i < len(str2) and str2[i] in (c, d): + i += 1 + return i == len(str2) +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + public boolean canMakeSubsequence(String str1, String str2) { + int i = 0, n = str2.length(); + for (char c : str1.toCharArray()) { + char d = c == 'z' ? 'a' : (char) (c + 1); + if (i < n && (str2.charAt(i) == c || str2.charAt(i) == d)) { + ++i; + } + } + return i == n; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + bool canMakeSubsequence(string str1, string str2) { + int i = 0, n = str2.size(); + for (char c : str1) { + char d = c == 'z' ? 'a' : c + 1; + if (i < n && (str2[i] == c || str2[i] == d)) { + ++i; + } + } + return i == n; + } +}; +``` + +### **Go** + +```go +func canMakeSubsequence(str1 string, str2 string) bool { + i, n := 0, len(str2) + for _, c := range str1 { + d := byte('a') + if c != 'z' { + d = byte(c + 1) + } + if i < n && (str2[i] == byte(c) || str2[i] == d) { + i++ + } + } + return i == n +} +``` + +### **TypeScript** + +```ts +function canMakeSubsequence(str1: string, str2: string): boolean { + let i = 0; + const n = str2.length; + for (const c of str1) { + const d = c === 'z' ? 'a' : String.fromCharCode(c.charCodeAt(0) + 1); + if (i < n && (str2[i] === c || str2[i] === d)) { + ++i; + } + } + return i === n; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/README_EN.md b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/README_EN.md new file mode 100644 index 0000000000000..d9c77bee14493 --- /dev/null +++ b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/README_EN.md @@ -0,0 +1,144 @@ +# [2825. Make String a Subsequence Using Cyclic Increments](https://leetcode.com/problems/make-string-a-subsequence-using-cyclic-increments) + +[中文文档](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README.md) + +## Description + +<p>You are given two <strong>0-indexed</strong> strings <code>str1</code> and <code>str2</code>.</p> + +<p>In an operation, you select a <strong>set</strong> of indices in <code>str1</code>, and for each index <code>i</code> in the set, increment <code>str1[i]</code> to the next character <strong>cyclically</strong>. That is <code>'a'</code> becomes <code>'b'</code>, <code>'b'</code> becomes <code>'c'</code>, and so on, and <code>'z'</code> becomes <code>'a'</code>.</p> + +<p>Return <code>true</code> <em>if it is possible to make </em><code>str2</code> <em>a subsequence of </em><code>str1</code> <em>by performing the operation <strong>at most once</strong></em>, <em>and</em> <code>false</code> <em>otherwise</em>.</p> + +<p><strong>Note:</strong> A subsequence of a string is a new string that is formed from the original string by deleting some (possibly none) of the characters without disturbing the relative positions of the remaining characters.</p> + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> str1 = "abc", str2 = "ad" +<strong>Output:</strong> true +<strong>Explanation:</strong> Select index 2 in str1. +Increment str1[2] to become 'd'. +Hence, str1 becomes "abd" and str2 is now a subsequence. Therefore, true is returned.</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> str1 = "zc", str2 = "ad" +<strong>Output:</strong> true +<strong>Explanation:</strong> Select indices 0 and 1 in str1. +Increment str1[0] to become 'a'. +Increment str1[1] to become 'd'. +Hence, str1 becomes "ad" and str2 is now a subsequence. Therefore, true is returned.</pre> + +<p><strong class="example">Example 3:</strong></p> + +<pre> +<strong>Input:</strong> str1 = "ab", str2 = "d" +<strong>Output:</strong> false +<strong>Explanation:</strong> In this example, it can be shown that it is impossible to make str2 a subsequence of str1 using the operation at most once. +Therefore, false is returned.</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>1 <= str1.length <= 10<sup>5</sup></code></li> + <li><code>1 <= str2.length <= 10<sup>5</sup></code></li> + <li><code>str1</code> and <code>str2</code> consist of only lowercase English letters.</li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def canMakeSubsequence(self, str1: str, str2: str) -> bool: + i = 0 + for c in str1: + d = "a" if c == "z" else chr(ord(c) + 1) + if i < len(str2) and str2[i] in (c, d): + i += 1 + return i == len(str2) +``` + +### **Java** + +```java +class Solution { + public boolean canMakeSubsequence(String str1, String str2) { + int i = 0, n = str2.length(); + for (char c : str1.toCharArray()) { + char d = c == 'z' ? 'a' : (char) (c + 1); + if (i < n && (str2.charAt(i) == c || str2.charAt(i) == d)) { + ++i; + } + } + return i == n; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + bool canMakeSubsequence(string str1, string str2) { + int i = 0, n = str2.size(); + for (char c : str1) { + char d = c == 'z' ? 'a' : c + 1; + if (i < n && (str2[i] == c || str2[i] == d)) { + ++i; + } + } + return i == n; + } +}; +``` + +### **Go** + +```go +func canMakeSubsequence(str1 string, str2 string) bool { + i, n := 0, len(str2) + for _, c := range str1 { + d := byte('a') + if c != 'z' { + d = byte(c + 1) + } + if i < n && (str2[i] == byte(c) || str2[i] == d) { + i++ + } + } + return i == n +} +``` + +### **TypeScript** + +```ts +function canMakeSubsequence(str1: string, str2: string): boolean { + let i = 0; + const n = str2.length; + for (const c of str1) { + const d = c === 'z' ? 'a' : String.fromCharCode(c.charCodeAt(0) + 1); + if (i < n && (str2[i] === c || str2[i] === d)) { + ++i; + } + } + return i === n; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.cpp b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.cpp new file mode 100644 index 0000000000000..0f3aef1f8ab9b --- /dev/null +++ b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + bool canMakeSubsequence(string str1, string str2) { + int i = 0, n = str2.size(); + for (char c : str1) { + char d = c == 'z' ? 'a' : c + 1; + if (i < n && (str2[i] == c || str2[i] == d)) { + ++i; + } + } + return i == n; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.go b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.go new file mode 100644 index 0000000000000..cf4854d6df804 --- /dev/null +++ b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.go @@ -0,0 +1,13 @@ +func canMakeSubsequence(str1 string, str2 string) bool { + i, n := 0, len(str2) + for _, c := range str1 { + d := byte('a') + if c != 'z' { + d = byte(c + 1) + } + if i < n && (str2[i] == byte(c) || str2[i] == d) { + i++ + } + } + return i == n +} \ No newline at end of file diff --git a/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.java b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.java new file mode 100644 index 0000000000000..9adce00bea6c1 --- /dev/null +++ b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.java @@ -0,0 +1,12 @@ +class Solution { + public boolean canMakeSubsequence(String str1, String str2) { + int i = 0, n = str2.length(); + for (char c : str1.toCharArray()) { + char d = c == 'z' ? 'a' : (char) (c + 1); + if (i < n && (str2.charAt(i) == c || str2.charAt(i) == d)) { + ++i; + } + } + return i == n; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.py b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.py new file mode 100644 index 0000000000000..d47922c516f73 --- /dev/null +++ b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.py @@ -0,0 +1,8 @@ +class Solution: + def canMakeSubsequence(self, str1: str, str2: str) -> bool: + i = 0 + for c in str1: + d = "a" if c == "z" else chr(ord(c) + 1) + if i < len(str2) and str2[i] in (c, d): + i += 1 + return i == len(str2) diff --git a/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.ts b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.ts new file mode 100644 index 0000000000000..9efebbaf5203b --- /dev/null +++ b/solution/2800-2899/2825.Make String a Subsequence Using Cyclic Increments/Solution.ts @@ -0,0 +1,11 @@ +function canMakeSubsequence(str1: string, str2: string): boolean { + let i = 0; + const n = str2.length; + for (const c of str1) { + const d = c === 'z' ? 'a' : String.fromCharCode(c.charCodeAt(0) + 1); + if (i < n && (str2[i] === c || str2[i] === d)) { + ++i; + } + } + return i === n; +} diff --git a/solution/2800-2899/2826.Sorting Three Groups/README.md b/solution/2800-2899/2826.Sorting Three Groups/README.md new file mode 100644 index 0000000000000..e99c4cefc2d27 --- /dev/null +++ b/solution/2800-2899/2826.Sorting Three Groups/README.md @@ -0,0 +1,261 @@ +# [2826. 将三个组排序](https://leetcode.cn/problems/sorting-three-groups) + +[English Version](/solution/2800-2899/2826.Sorting%20Three%20Groups/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +<p>给你一个下标从 <strong>0</strong> 开始长度为 <code>n</code> 的整数数组 <code>nums</code> 。<br /> +<br /> +从 <code>0</code> 到 <code>n - 1</code> 的数字被分为编号从 <code>1</code> 到 <code>3</code> 的三个组,数字 <code>i</code> 属于组 <code>nums[i]</code> 。注意,有的组可能是 <strong>空的</strong> 。<br /> +<br /> +你可以执行以下操作任意次:</p> + +<ul> + <li>选择数字 <code>x</code> 并改变它的组。更正式的,你可以将 <code>nums[x]</code> 改为数字 <code>1</code> 到 <code>3</code> 中的任意一个。</li> +</ul> + +<p>你将按照以下过程构建一个新的数组 <code>res</code> :</p> + +<ol> + <li>将每个组中的数字分别排序。</li> + <li>将组 <code>1</code> ,<code>2</code> 和 <code>3</code> 中的元素 <strong>依次</strong> 连接以得到 <code>res</code> 。</li> +</ol> + +<p>如果得到的 <code>res</code> 是 <strong>非递减</strong>顺序的,那么我们称数组 <code>nums</code> 是 <strong>美丽数组</strong> 。</p> + +<p>请你返回将<em> </em><code>nums</code> 变为 <strong>美丽数组</strong> 需要的最少步数。</p> + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<b>输入:</b>nums = [2,1,3,2,1] +<b>输出:</b>3 +<b>解释:</b>以下三步操作是最优方案: +1. 将 nums[0] 变为 1 。 +2. 将 nums[2] 变为 1 。 +3. 将 nums[3] 变为 1 。 +执行以上操作后,将每组中的数字排序,组 1 为 [0,1,2,3,4] ,组 2 和组 3 都为空。所以 res 等于 [0,1,2,3,4] ,它是非递减顺序的。 +三步操作是最少需要的步数。 +</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<b>输入:</b>nums = [1,3,2,1,3,3] +<b>输出:</b>2 +<b>解释:</b>以下两步操作是最优方案: +1. 将 nums[1] 变为 1 。 +2. 将 nums[2] 变为 1 。 +执行以上操作后,将每组中的数字排序,组 1 为 [0,1,2,3] ,组 2 为空,组 3 为 [4,5] 。所以 res 等于 [0,1,2,3,4,5] ,它是非递减顺序的。 +两步操作是最少需要的步数。 +</pre> + +<p><strong class="example">示例 3:</strong></p> + +<pre> +<b>输入:</b>nums = [2,2,2,2,3,3] +<b>输出:</b>0 +<b>解释:</b>不需要执行任何操作。 +组 1 为空,组 2 为 [0,1,2,3] ,组 3 为 [4,5] 。所以 res 等于 [0,1,2,3,4,5] ,它是非递减顺序的。 +</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>1 <= nums.length <= 100</code></li> + <li><code>1 <= nums[i] <= 3</code></li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:动态规划** + +我们定义 $f[i][j]$ 表示将前 $i$ 个数变成美丽数组,并且第 $i$ 个数变成 $j+1$ 的最少操作次数。那么答案就是 $min(f[n][0], f[n][1], f[n][2])$。 + +我们可以枚举第 $i$ 个数变成 $j+1$ 的所有情况,然后取最小值。这里我们可以用滚动数组优化空间复杂度。 + +时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。 + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def minimumOperations(self, nums: List[int]) -> int: + f = g = h = 0 + for x in nums: + ff = gg = hh = 0 + if x == 1: + ff = f + gg = min(f, g) + 1 + hh = min(f, g, h) + 1 + elif x == 2: + ff = f + 1 + gg = min(f, g) + hh = min(f, g, h) + 1 + else: + ff = f + 1 + gg = min(f, g) + 1 + hh = min(f, g, h) + f, g, h = ff, gg, hh + return min(f, g, h) +``` + +```python +class Solution: + def minimumOperations(self, nums: List[int]) -> int: + f = [0] * 3 + for x in nums: + g = [0] * 3 + if x == 1: + g[0] = f[0] + g[1] = min(f[:2]) + 1 + g[2] = min(f) + 1 + elif x == 2: + g[0] = f[0] + 1 + g[1] = min(f[:2]) + g[2] = min(f) + 1 + else: + g[0] = f[0] + 1 + g[1] = min(f[:2]) + 1 + g[2] = min(f) + f = g + return min(f) +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + public int minimumOperations(List<Integer> nums) { + int[] f = new int[3]; + for (int x : nums) { + int[] g = new int[3]; + if (x == 1) { + g[0] = f[0]; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else if (x == 2) { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]); + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])); + } + f = g; + } + return Math.min(f[0], Math.min(f[1], f[2])); + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minimumOperations(vector<int>& nums) { + vector<int> f(3); + for (int x : nums) { + vector<int> g(3); + if (x == 1) { + g[0] = f[0]; + g[1] = min(f[0], f[1]) + 1; + g[2] = min({f[0], f[1], f[2]}) + 1; + } else if (x == 2) { + g[0] = f[0] + 1; + g[1] = min(f[0], f[1]); + g[2] = min(f[0], min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = min(f[0], f[1]) + 1; + g[2] = min(f[0], min(f[1], f[2])); + } + f = move(g); + } + return min({f[0], f[1], f[2]}); + } +}; +``` + +### **Go** + +```go +func minimumOperations(nums []int) int { + f := make([]int, 3) + for _, x := range nums { + g := make([]int, 3) + if x == 1 { + g[0] = f[0] + g[1] = min(f[0], f[1]) + 1 + g[2] = min(f[0], min(f[1], f[2])) + 1 + } else if x == 2 { + g[0] = f[0] + 1 + g[1] = min(f[0], f[1]) + g[2] = min(f[0], min(f[1], f[2])) + 1 + } else { + g[0] = f[0] + 1 + g[1] = min(f[0], f[1]) + 1 + g[2] = min(f[0], min(f[1], f[2])) + } + f = g + } + return min(f[0], min(f[1], f[2])) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function minimumOperations(nums: number[]): number { + let f: number[] = new Array(3).fill(0); + for (const x of nums) { + const g: number[] = new Array(3).fill(0); + if (x === 1) { + g[0] = f[0]; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else if (x === 2) { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]); + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])); + } + f = g; + } + return Math.min(...f); +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2826.Sorting Three Groups/README_EN.md b/solution/2800-2899/2826.Sorting Three Groups/README_EN.md new file mode 100644 index 0000000000000..a089b38e21bc6 --- /dev/null +++ b/solution/2800-2899/2826.Sorting Three Groups/README_EN.md @@ -0,0 +1,243 @@ +# [2826. Sorting Three Groups](https://leetcode.com/problems/sorting-three-groups) + +[中文文档](/solution/2800-2899/2826.Sorting%20Three%20Groups/README.md) + +## Description + +<p>You are given a <strong>0-indexed</strong> integer array <code>nums</code> of length <code>n</code>.<br /> +<br /> +The numbers from <code>0</code> to <code>n - 1</code> are divided into three groups numbered from <code>1</code> to <code>3</code>, where number <code>i</code> belongs to group <code>nums[i]</code>. Notice that some groups may be <strong>empty</strong>.<br /> +<br /> +You are allowed to perform this operation any number of times:</p> + +<ul> + <li>Pick number <code>x</code> and change its group. More formally, change <code>nums[x]</code> to any number from <code>1</code> to <code>3</code>.</li> +</ul> + +<p>A new array <code>res</code> is constructed using the following procedure:</p> + +<ol> + <li>Sort the numbers in each group independently.</li> + <li>Append the elements of groups <code>1</code>, <code>2</code>, and <code>3</code> to <code>res</code> <strong>in this order</strong>.</li> +</ol> + +<p>Array <code>nums</code> is called a <strong>beautiful array</strong> if the constructed array <code>res</code> is sorted in <strong>non-decreasing</strong> order.</p> + +<p>Return <em>the <strong>minimum</strong> number of operations to make </em><code>nums</code><em> a <strong>beautiful array</strong></em>.</p> + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> nums = [2,1,3,2,1] +<strong>Output:</strong> 3 +<strong>Explanation:</strong> It's optimal to perform three operations: +1. change nums[0] to 1. +2. change nums[2] to 1. +3. change nums[3] to 1. +After performing the operations and sorting the numbers in each group, group 1 becomes equal to [0,1,2,3,4] and group 2 and group 3 become empty. Hence, res is equal to [0,1,2,3,4] which is sorted in non-decreasing order. +It can be proven that there is no valid sequence of less than three operations. +</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> nums = [1,3,2,1,3,3] +<strong>Output:</strong> 2 +<strong>Explanation:</strong> It's optimal to perform two operations: +1. change nums[1] to 1. +2. change nums[2] to 1. +After performing the operations and sorting the numbers in each group, group 1 becomes equal to [0,1,2,3], group 2 becomes empty, and group 3 becomes equal to [4,5]. Hence, res is equal to [0,1,2,3,4,5] which is sorted in non-decreasing order. +It can be proven that there is no valid sequence of less than two operations. +</pre> + +<p><strong class="example">Example 3:</strong></p> + +<pre> +<strong>Input:</strong> nums = [2,2,2,2,3,3] +<strong>Output:</strong> 0 +<strong>Explanation:</strong> It's optimal to not perform operations. +After sorting the numbers in each group, group 1 becomes empty, group 2 becomes equal to [0,1,2,3] and group 3 becomes equal to [4,5]. Hence, res is equal to [0,1,2,3,4,5] which is sorted in non-decreasing order. +</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>1 <= nums.length <= 100</code></li> + <li><code>1 <= nums[i] <= 3</code></li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def minimumOperations(self, nums: List[int]) -> int: + f = g = h = 0 + for x in nums: + ff = gg = hh = 0 + if x == 1: + ff = f + gg = min(f, g) + 1 + hh = min(f, g, h) + 1 + elif x == 2: + ff = f + 1 + gg = min(f, g) + hh = min(f, g, h) + 1 + else: + ff = f + 1 + gg = min(f, g) + 1 + hh = min(f, g, h) + f, g, h = ff, gg, hh + return min(f, g, h) +``` + +```python +class Solution: + def minimumOperations(self, nums: List[int]) -> int: + f = [0] * 3 + for x in nums: + g = [0] * 3 + if x == 1: + g[0] = f[0] + g[1] = min(f[:2]) + 1 + g[2] = min(f) + 1 + elif x == 2: + g[0] = f[0] + 1 + g[1] = min(f[:2]) + g[2] = min(f) + 1 + else: + g[0] = f[0] + 1 + g[1] = min(f[:2]) + 1 + g[2] = min(f) + f = g + return min(f) +``` + +### **Java** + +```java +class Solution { + public int minimumOperations(List<Integer> nums) { + int[] f = new int[3]; + for (int x : nums) { + int[] g = new int[3]; + if (x == 1) { + g[0] = f[0]; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else if (x == 2) { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]); + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])); + } + f = g; + } + return Math.min(f[0], Math.min(f[1], f[2])); + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minimumOperations(vector<int>& nums) { + vector<int> f(3); + for (int x : nums) { + vector<int> g(3); + if (x == 1) { + g[0] = f[0]; + g[1] = min(f[0], f[1]) + 1; + g[2] = min({f[0], f[1], f[2]}) + 1; + } else if (x == 2) { + g[0] = f[0] + 1; + g[1] = min(f[0], f[1]); + g[2] = min(f[0], min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = min(f[0], f[1]) + 1; + g[2] = min(f[0], min(f[1], f[2])); + } + f = move(g); + } + return min({f[0], f[1], f[2]}); + } +}; +``` + +### **Go** + +```go +func minimumOperations(nums []int) int { + f := make([]int, 3) + for _, x := range nums { + g := make([]int, 3) + if x == 1 { + g[0] = f[0] + g[1] = min(f[0], f[1]) + 1 + g[2] = min(f[0], min(f[1], f[2])) + 1 + } else if x == 2 { + g[0] = f[0] + 1 + g[1] = min(f[0], f[1]) + g[2] = min(f[0], min(f[1], f[2])) + 1 + } else { + g[0] = f[0] + 1 + g[1] = min(f[0], f[1]) + 1 + g[2] = min(f[0], min(f[1], f[2])) + } + f = g + } + return min(f[0], min(f[1], f[2])) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function minimumOperations(nums: number[]): number { + let f: number[] = new Array(3).fill(0); + for (const x of nums) { + const g: number[] = new Array(3).fill(0); + if (x === 1) { + g[0] = f[0]; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else if (x === 2) { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]); + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])); + } + f = g; + } + return Math.min(...f); +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2826.Sorting Three Groups/Solution.cpp b/solution/2800-2899/2826.Sorting Three Groups/Solution.cpp new file mode 100644 index 0000000000000..58e0b94d63e6e --- /dev/null +++ b/solution/2800-2899/2826.Sorting Three Groups/Solution.cpp @@ -0,0 +1,24 @@ +class Solution { +public: + int minimumOperations(vector<int>& nums) { + vector<int> f(3); + for (int x : nums) { + vector<int> g(3); + if (x == 1) { + g[0] = f[0]; + g[1] = min(f[0], f[1]) + 1; + g[2] = min({f[0], f[1], f[2]}) + 1; + } else if (x == 2) { + g[0] = f[0] + 1; + g[1] = min(f[0], f[1]); + g[2] = min(f[0], min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = min(f[0], f[1]) + 1; + g[2] = min(f[0], min(f[1], f[2])); + } + f = move(g); + } + return min({f[0], f[1], f[2]}); + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2826.Sorting Three Groups/Solution.go b/solution/2800-2899/2826.Sorting Three Groups/Solution.go new file mode 100644 index 0000000000000..ed0f1237c7cbb --- /dev/null +++ b/solution/2800-2899/2826.Sorting Three Groups/Solution.go @@ -0,0 +1,28 @@ +func minimumOperations(nums []int) int { + f := make([]int, 3) + for _, x := range nums { + g := make([]int, 3) + if x == 1 { + g[0] = f[0] + g[1] = min(f[0], f[1]) + 1 + g[2] = min(f[0], min(f[1], f[2])) + 1 + } else if x == 2 { + g[0] = f[0] + 1 + g[1] = min(f[0], f[1]) + g[2] = min(f[0], min(f[1], f[2])) + 1 + } else { + g[0] = f[0] + 1 + g[1] = min(f[0], f[1]) + 1 + g[2] = min(f[0], min(f[1], f[2])) + } + f = g + } + return min(f[0], min(f[1], f[2])) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} \ No newline at end of file diff --git a/solution/2800-2899/2826.Sorting Three Groups/Solution.java b/solution/2800-2899/2826.Sorting Three Groups/Solution.java new file mode 100644 index 0000000000000..41ed065505650 --- /dev/null +++ b/solution/2800-2899/2826.Sorting Three Groups/Solution.java @@ -0,0 +1,23 @@ +class Solution { + public int minimumOperations(List<Integer> nums) { + int[] f = new int[3]; + for (int x : nums) { + int[] g = new int[3]; + if (x == 1) { + g[0] = f[0]; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else if (x == 2) { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]); + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])); + } + f = g; + } + return Math.min(f[0], Math.min(f[1], f[2])); + } +} \ No newline at end of file diff --git a/solution/2800-2899/2826.Sorting Three Groups/Solution.py b/solution/2800-2899/2826.Sorting Three Groups/Solution.py new file mode 100644 index 0000000000000..254580d561ea0 --- /dev/null +++ b/solution/2800-2899/2826.Sorting Three Groups/Solution.py @@ -0,0 +1,19 @@ +class Solution: + def minimumOperations(self, nums: List[int]) -> int: + f = [0] * 3 + for x in nums: + g = [0] * 3 + if x == 1: + g[0] = f[0] + g[1] = min(f[:2]) + 1 + g[2] = min(f) + 1 + elif x == 2: + g[0] = f[0] + 1 + g[1] = min(f[:2]) + g[2] = min(f) + 1 + else: + g[0] = f[0] + 1 + g[1] = min(f[:2]) + 1 + g[2] = min(f) + f = g + return min(f) diff --git a/solution/2800-2899/2826.Sorting Three Groups/Solution.ts b/solution/2800-2899/2826.Sorting Three Groups/Solution.ts new file mode 100644 index 0000000000000..00e8cc4ca8632 --- /dev/null +++ b/solution/2800-2899/2826.Sorting Three Groups/Solution.ts @@ -0,0 +1,21 @@ +function minimumOperations(nums: number[]): number { + let f: number[] = new Array(3).fill(0); + for (const x of nums) { + const g: number[] = new Array(3).fill(0); + if (x === 1) { + g[0] = f[0]; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else if (x === 2) { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]); + g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1; + } else { + g[0] = f[0] + 1; + g[1] = Math.min(f[0], f[1]) + 1; + g[2] = Math.min(f[0], Math.min(f[1], f[2])); + } + f = g; + } + return Math.min(...f); +} diff --git a/solution/2800-2899/2827.Number of Beautiful Integers in the Range/README.md b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/README.md new file mode 100644 index 0000000000000..48271e9bbfa8a --- /dev/null +++ b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/README.md @@ -0,0 +1,343 @@ +# [2827. 范围中美丽整数的数目](https://leetcode.cn/problems/number-of-beautiful-integers-in-the-range) + +[English Version](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +<p>给你正整数 <code>low</code> ,<code>high</code> 和 <code>k</code> 。</p> + +<p>如果一个数满足以下两个条件,那么它是 <strong>美丽的</strong> :</p> + +<ul> + <li>偶数数位的数目与奇数数位的数目相同。</li> + <li>这个整数可以被 <code>k</code> 整除。</li> +</ul> + +<p>请你返回范围 <code>[low, high]</code> 中美丽整数的数目。</p> + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<b>输入:</b>low = 10, high = 20, k = 3 +<b>输出:</b>2 +<b>解释:</b>给定范围中有 2 个美丽数字:[12,18] +- 12 是美丽整数,因为它有 1 个奇数数位和 1 个偶数数位,而且可以被 k = 3 整除。 +- 18 是美丽整数,因为它有 1 个奇数数位和 1 个偶数数位,而且可以被 k = 3 整除。 +以下是一些不是美丽整数的例子: +- 16 不是美丽整数,因为它不能被 k = 3 整除。 +- 15 不是美丽整数,因为它的奇数数位和偶数数位的数目不相等。 +给定范围内总共有 2 个美丽整数。 +</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<b>输入:</b>low = 1, high = 10, k = 1 +<b>输出:</b>1 +<b>解释:</b>给定范围中有 1 个美丽数字:[10] +- 10 是美丽整数,因为它有 1 个奇数数位和 1 个偶数数位,而且可以被 k = 1 整除。 +给定范围内总共有 1 个美丽整数。 +</pre> + +<p><strong class="example">示例 3:</strong></p> + +<pre> +<b>输入:</b>low = 5, high = 5, k = 2 +<b>输出:</b>0 +<b>解释:</b>给定范围中有 0 个美丽数字。 +- 5 不是美丽整数,因为它的奇数数位和偶数数位的数目不相等。 +</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>0 < low <= high <= 10<sup>9</sup></code></li> + <li><code>0 < k <= 20</code></li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:数位 DP** + +我们注意到,题目求的是区间 $[low, high]$ 内的步进数的个数,对于这种区间 $[l,..r]$ 的问题,我们通常可以考虑转化为求 $[1, r]$ 和 $[1, l-1]$ 的答案,然后相减即可。另外,题目中只涉及到不同数位之间的关系,而不涉及具体的数值,因此我们可以考虑使用数位 DP 来解决。 + +我们设计一个函数 $dfs(pos, mod, diff, lead, limit)$,表示当前处理到第 $pos$ 位,当前数字模 $k$ 的结果为 $mod$,当前数字的奇偶数位差为 $diff$,当前数字是否有前导零为 $lead$,当前数字是否达到上界为 $limit$ 时的方案数。 + +函数 $dfs(pos, mod, diff, lead, limit)$ 的执行逻辑如下: + +如果 $pos$ 超出了 $num$ 的长度,说明我们已经处理完了所有数位,如果此时 $mod=0$,并且 $diff=0$,说明当前数字满足题目要求,我们返回 $1$,否则返回 $0$。 + +否则,我们计算得到当前数位的上界 $up$,然后在 $[0,..up]$ 范围内枚举当前数位的数字 $i$: + +- 如果 $i=0$ 且 $lead$ 为真,说明当前数字只包含前导零,我们递归计算 $dfs(pos + 1, mod, diff, 1, limit\ and\ i=up)$ 的值并累加到答案中; +- 否则,我们根据 $i$ 的奇偶性更新 $diff$ 的值,然后递归计算 $dfs(pos + 1, (mod \times 10 + i) \bmod k, diff, 0, limit\ and\ i=up)$ 的值并累加到答案中。 + +最终我们返回答案。 + +在主函数中,我们分别计算 $[1, high]$ 和 $[1, low-1]$ 的答案 $a$ 和 $b$,最终答案为 $a-b$。 + +时间复杂度 $O((\log M)^2 \times k \times |\Sigma|)$,空间复杂度 $O((\log M)^2 \times k \times)$,其中 $M$ 表示 $high$ 数字的大小,而 $|\Sigma|$ 表示数字集合。 + +相似题目: + +- [2719. 统计整数数目](/solution/2700-2799/2719.Count%20of%20Integers/README.md) + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def numberOfBeautifulIntegers(self, low: int, high: int, k: int) -> int: + @cache + def dfs(pos: int, mod: int, diff: int, lead: int, limit: int) -> int: + if pos >= len(s): + return mod == 0 and diff == 10 + up = int(s[pos]) if limit else 9 + ans = 0 + for i in range(up + 1): + if i == 0 and lead: + ans += dfs(pos + 1, mod, diff, 1, limit and i == up) + else: + nxt = diff + (1 if i % 2 == 1 else -1) + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, 0, limit and i == up) + return ans + + s = str(high) + a = dfs(0, 0, 10, 1, 1) + dfs.cache_clear() + s = str(low - 1) + b = dfs(0, 0, 10, 1, 1) + return a - b +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + private String s; + private int k; + private Integer[][][] f = new Integer[11][21][21]; + + public int numberOfBeautifulIntegers(int low, int high, int k) { + this.k = k; + s = String.valueOf(high); + int a = dfs(0, 0, 10, true, true); + s = String.valueOf(low - 1); + f = new Integer[11][21][21]; + int b = dfs(0, 0, 10, true, true); + return a - b; + } + + private int dfs(int pos, int mod, int diff, boolean lead, boolean limit) { + if (pos >= s.length()) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != null) { + return f[pos][mod][diff]; + } + int ans = 0; + int up = limit ? s.charAt(pos) - '0' : 9; + for (int i = 0; i <= up; ++i) { + if (i == 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i == up); + } else { + int nxt = diff + (i % 2 == 1 ? 1 : -1); + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numberOfBeautifulIntegers(int low, int high, int k) { + int f[11][21][21]; + memset(f, -1, sizeof(f)); + string s = to_string(high); + + function<int(int, int, int, bool, bool)> dfs = [&](int pos, int mod, int diff, bool lead, bool limit) { + if (pos >= s.size()) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != -1) { + return f[pos][mod][diff]; + } + int ans = 0; + int up = limit ? s[pos] - '0' : 9; + for (int i = 0; i <= up; ++i) { + if (i == 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i == up); + } else { + int nxt = diff + (i % 2 == 1 ? 1 : -1); + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + }; + + int a = dfs(0, 0, 10, true, true); + memset(f, -1, sizeof(f)); + s = to_string(low - 1); + int b = dfs(0, 0, 10, true, true); + return a - b; + } +}; +``` + +### **Go** + +```go +func numberOfBeautifulIntegers(low int, high int, k int) int { + s := strconv.Itoa(high) + f := g(len(s), k, 21) + + var dfs func(pos, mod, diff int, lead, limit bool) int + dfs = func(pos, mod, diff int, lead, limit bool) int { + if pos >= len(s) { + if mod == 0 && diff == 10 { + return 1 + } + return 0 + } + if !lead && !limit && f[pos][mod][diff] != -1 { + return f[pos][mod][diff] + } + up := 9 + if limit { + up = int(s[pos] - '0') + } + ans := 0 + for i := 0; i <= up; i++ { + if i == 0 && lead { + ans += dfs(pos+1, mod, diff, true, limit && i == up) + } else { + nxt := diff + 1 + if i%2 == 0 { + nxt -= 2 + } + ans += dfs(pos+1, (mod*10+i)%k, nxt, false, limit && i == up) + } + } + if !lead && !limit { + f[pos][mod][diff] = ans + } + return ans + } + + a := dfs(0, 0, 10, true, true) + s = strconv.Itoa(low - 1) + f = g(len(s), k, 21) + b := dfs(0, 0, 10, true, true) + return a - b +} + +func g(m, n, k int) [][][]int { + f := make([][][]int, m) + for i := 0; i < m; i++ { + f[i] = make([][]int, n) + for j := 0; j < n; j++ { + f[i][j] = make([]int, k) + for d := 0; d < k; d++ { + f[i][j][d] = -1 + } + } + } + return f +} +``` + +### **TypeScript** + +```ts +function numberOfBeautifulIntegers( + low: number, + high: number, + k: number, +): number { + let s = String(high); + let f: number[][][] = Array(11) + .fill(0) + .map(() => + Array(21) + .fill(0) + .map(() => Array(21).fill(-1)), + ); + const dfs = ( + pos: number, + mod: number, + diff: number, + lead: boolean, + limit: boolean, + ): number => { + if (pos >= s.length) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != -1) { + return f[pos][mod][diff]; + } + let ans = 0; + const up = limit ? Number(s[pos]) : 9; + for (let i = 0; i <= up; ++i) { + if (i === 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i === up); + } else { + const nxt = diff + (i % 2 ? 1 : -1); + ans += dfs( + pos + 1, + (mod * 10 + i) % k, + nxt, + false, + limit && i === up, + ); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + }; + const a = dfs(0, 0, 10, true, true); + s = String(low - 1); + f = Array(11) + .fill(0) + .map(() => + Array(21) + .fill(0) + .map(() => Array(21).fill(-1)), + ); + const b = dfs(0, 0, 10, true, true); + return a - b; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2827.Number of Beautiful Integers in the Range/README_EN.md b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/README_EN.md new file mode 100644 index 0000000000000..24f9944f47ee0 --- /dev/null +++ b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/README_EN.md @@ -0,0 +1,308 @@ +# [2827. Number of Beautiful Integers in the Range](https://leetcode.com/problems/number-of-beautiful-integers-in-the-range) + +[中文文档](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README.md) + +## Description + +<p>You are given positive integers <code>low</code>, <code>high</code>, and <code>k</code>.</p> + +<p>A number is <strong>beautiful</strong> if it meets both of the following conditions:</p> + +<ul> + <li>The count of even digits in the number is equal to the count of odd digits.</li> + <li>The number is divisible by <code>k</code>.</li> +</ul> + +<p>Return <em>the number of beautiful integers in the range</em> <code>[low, high]</code>.</p> + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> low = 10, high = 20, k = 3 +<strong>Output:</strong> 2 +<strong>Explanation:</strong> There are 2 beautiful integers in the given range: [12,18]. +- 12 is beautiful because it contains 1 odd digit and 1 even digit, and is divisible by k = 3. +- 18 is beautiful because it contains 1 odd digit and 1 even digit, and is divisible by k = 3. +Additionally we can see that: +- 16 is not beautiful because it is not divisible by k = 3. +- 15 is not beautiful because it does not contain equal counts even and odd digits. +It can be shown that there are only 2 beautiful integers in the given range. +</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> low = 1, high = 10, k = 1 +<strong>Output:</strong> 1 +<strong>Explanation:</strong> There is 1 beautiful integer in the given range: [10]. +- 10 is beautiful because it contains 1 odd digit and 1 even digit, and is divisible by k = 1. +It can be shown that there is only 1 beautiful integer in the given range. +</pre> + +<p><strong class="example">Example 3:</strong></p> + +<pre> +<strong>Input:</strong> low = 5, high = 5, k = 2 +<strong>Output:</strong> 0 +<strong>Explanation:</strong> There are 0 beautiful integers in the given range. +- 5 is not beautiful because it is not divisible by k = 2 and it does not contain equal even and odd digits. +</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>0 < low <= high <= 10<sup>9</sup></code></li> + <li><code>0 < k <= 20</code></li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def numberOfBeautifulIntegers(self, low: int, high: int, k: int) -> int: + @cache + def dfs(pos: int, mod: int, diff: int, lead: int, limit: int) -> int: + if pos >= len(s): + return mod == 0 and diff == 10 + up = int(s[pos]) if limit else 9 + ans = 0 + for i in range(up + 1): + if i == 0 and lead: + ans += dfs(pos + 1, mod, diff, 1, limit and i == up) + else: + nxt = diff + (1 if i % 2 == 1 else -1) + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, 0, limit and i == up) + return ans + + s = str(high) + a = dfs(0, 0, 10, 1, 1) + dfs.cache_clear() + s = str(low - 1) + b = dfs(0, 0, 10, 1, 1) + return a - b +``` + +### **Java** + +```java +class Solution { + private String s; + private int k; + private Integer[][][] f = new Integer[11][21][21]; + + public int numberOfBeautifulIntegers(int low, int high, int k) { + this.k = k; + s = String.valueOf(high); + int a = dfs(0, 0, 10, true, true); + s = String.valueOf(low - 1); + f = new Integer[11][21][21]; + int b = dfs(0, 0, 10, true, true); + return a - b; + } + + private int dfs(int pos, int mod, int diff, boolean lead, boolean limit) { + if (pos >= s.length()) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != null) { + return f[pos][mod][diff]; + } + int ans = 0; + int up = limit ? s.charAt(pos) - '0' : 9; + for (int i = 0; i <= up; ++i) { + if (i == 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i == up); + } else { + int nxt = diff + (i % 2 == 1 ? 1 : -1); + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numberOfBeautifulIntegers(int low, int high, int k) { + int f[11][21][21]; + memset(f, -1, sizeof(f)); + string s = to_string(high); + + function<int(int, int, int, bool, bool)> dfs = [&](int pos, int mod, int diff, bool lead, bool limit) { + if (pos >= s.size()) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != -1) { + return f[pos][mod][diff]; + } + int ans = 0; + int up = limit ? s[pos] - '0' : 9; + for (int i = 0; i <= up; ++i) { + if (i == 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i == up); + } else { + int nxt = diff + (i % 2 == 1 ? 1 : -1); + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + }; + + int a = dfs(0, 0, 10, true, true); + memset(f, -1, sizeof(f)); + s = to_string(low - 1); + int b = dfs(0, 0, 10, true, true); + return a - b; + } +}; +``` + +### **Go** + +```go +func numberOfBeautifulIntegers(low int, high int, k int) int { + s := strconv.Itoa(high) + f := g(len(s), k, 21) + + var dfs func(pos, mod, diff int, lead, limit bool) int + dfs = func(pos, mod, diff int, lead, limit bool) int { + if pos >= len(s) { + if mod == 0 && diff == 10 { + return 1 + } + return 0 + } + if !lead && !limit && f[pos][mod][diff] != -1 { + return f[pos][mod][diff] + } + up := 9 + if limit { + up = int(s[pos] - '0') + } + ans := 0 + for i := 0; i <= up; i++ { + if i == 0 && lead { + ans += dfs(pos+1, mod, diff, true, limit && i == up) + } else { + nxt := diff + 1 + if i%2 == 0 { + nxt -= 2 + } + ans += dfs(pos+1, (mod*10+i)%k, nxt, false, limit && i == up) + } + } + if !lead && !limit { + f[pos][mod][diff] = ans + } + return ans + } + + a := dfs(0, 0, 10, true, true) + s = strconv.Itoa(low - 1) + f = g(len(s), k, 21) + b := dfs(0, 0, 10, true, true) + return a - b +} + +func g(m, n, k int) [][][]int { + f := make([][][]int, m) + for i := 0; i < m; i++ { + f[i] = make([][]int, n) + for j := 0; j < n; j++ { + f[i][j] = make([]int, k) + for d := 0; d < k; d++ { + f[i][j][d] = -1 + } + } + } + return f +} +``` + +### **TypeScript** + +```ts +function numberOfBeautifulIntegers( + low: number, + high: number, + k: number, +): number { + let s = String(high); + let f: number[][][] = Array(11) + .fill(0) + .map(() => + Array(21) + .fill(0) + .map(() => Array(21).fill(-1)), + ); + const dfs = ( + pos: number, + mod: number, + diff: number, + lead: boolean, + limit: boolean, + ): number => { + if (pos >= s.length) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != -1) { + return f[pos][mod][diff]; + } + let ans = 0; + const up = limit ? Number(s[pos]) : 9; + for (let i = 0; i <= up; ++i) { + if (i === 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i === up); + } else { + const nxt = diff + (i % 2 ? 1 : -1); + ans += dfs( + pos + 1, + (mod * 10 + i) % k, + nxt, + false, + limit && i === up, + ); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + }; + const a = dfs(0, 0, 10, true, true); + s = String(low - 1); + f = Array(11) + .fill(0) + .map(() => + Array(21) + .fill(0) + .map(() => Array(21).fill(-1)), + ); + const b = dfs(0, 0, 10, true, true); + return a - b; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.cpp b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.cpp new file mode 100644 index 0000000000000..0a33f58f8e945 --- /dev/null +++ b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.cpp @@ -0,0 +1,37 @@ +class Solution { +public: + int numberOfBeautifulIntegers(int low, int high, int k) { + int f[11][21][21]; + memset(f, -1, sizeof(f)); + string s = to_string(high); + + function<int(int, int, int, bool, bool)> dfs = [&](int pos, int mod, int diff, bool lead, bool limit) { + if (pos >= s.size()) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != -1) { + return f[pos][mod][diff]; + } + int ans = 0; + int up = limit ? s[pos] - '0' : 9; + for (int i = 0; i <= up; ++i) { + if (i == 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i == up); + } else { + int nxt = diff + (i % 2 == 1 ? 1 : -1); + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + }; + + int a = dfs(0, 0, 10, true, true); + memset(f, -1, sizeof(f)); + s = to_string(low - 1); + int b = dfs(0, 0, 10, true, true); + return a - b; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.go b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.go new file mode 100644 index 0000000000000..dc89d3497d164 --- /dev/null +++ b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.go @@ -0,0 +1,57 @@ +func numberOfBeautifulIntegers(low int, high int, k int) int { + s := strconv.Itoa(high) + f := g(len(s), k, 21) + + var dfs func(pos, mod, diff int, lead, limit bool) int + dfs = func(pos, mod, diff int, lead, limit bool) int { + if pos >= len(s) { + if mod == 0 && diff == 10 { + return 1 + } + return 0 + } + if !lead && !limit && f[pos][mod][diff] != -1 { + return f[pos][mod][diff] + } + up := 9 + if limit { + up = int(s[pos] - '0') + } + ans := 0 + for i := 0; i <= up; i++ { + if i == 0 && lead { + ans += dfs(pos+1, mod, diff, true, limit && i == up) + } else { + nxt := diff + 1 + if i%2 == 0 { + nxt -= 2 + } + ans += dfs(pos+1, (mod*10+i)%k, nxt, false, limit && i == up) + } + } + if !lead && !limit { + f[pos][mod][diff] = ans + } + return ans + } + + a := dfs(0, 0, 10, true, true) + s = strconv.Itoa(low - 1) + f = g(len(s), k, 21) + b := dfs(0, 0, 10, true, true) + return a - b +} + +func g(m, n, k int) [][][]int { + f := make([][][]int, m) + for i := 0; i < m; i++ { + f[i] = make([][]int, n) + for j := 0; j < n; j++ { + f[i][j] = make([]int, k) + for d := 0; d < k; d++ { + f[i][j][d] = -1 + } + } + } + return f +} \ No newline at end of file diff --git a/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.java b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.java new file mode 100644 index 0000000000000..1ad5d40529f8a --- /dev/null +++ b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.java @@ -0,0 +1,38 @@ +class Solution { + private String s; + private int k; + private Integer[][][] f = new Integer[11][21][21]; + + public int numberOfBeautifulIntegers(int low, int high, int k) { + this.k = k; + s = String.valueOf(high); + int a = dfs(0, 0, 10, true, true); + s = String.valueOf(low - 1); + f = new Integer[11][21][21]; + int b = dfs(0, 0, 10, true, true); + return a - b; + } + + private int dfs(int pos, int mod, int diff, boolean lead, boolean limit) { + if (pos >= s.length()) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != null) { + return f[pos][mod][diff]; + } + int ans = 0; + int up = limit ? s.charAt(pos) - '0' : 9; + for (int i = 0; i <= up; ++i) { + if (i == 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i == up); + } else { + int nxt = diff + (i % 2 == 1 ? 1 : -1); + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, false, limit && i == up); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.py b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.py new file mode 100644 index 0000000000000..a307e421c4f92 --- /dev/null +++ b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.py @@ -0,0 +1,22 @@ +class Solution: + def numberOfBeautifulIntegers(self, low: int, high: int, k: int) -> int: + @cache + def dfs(pos: int, mod: int, diff: int, lead: int, limit: int) -> int: + if pos >= len(s): + return mod == 0 and diff == 10 + up = int(s[pos]) if limit else 9 + ans = 0 + for i in range(up + 1): + if i == 0 and lead: + ans += dfs(pos + 1, mod, diff, 1, limit and i == up) + else: + nxt = diff + (1 if i % 2 == 1 else -1) + ans += dfs(pos + 1, (mod * 10 + i) % k, nxt, 0, limit and i == up) + return ans + + s = str(high) + a = dfs(0, 0, 10, 1, 1) + dfs.cache_clear() + s = str(low - 1) + b = dfs(0, 0, 10, 1, 1) + return a - b diff --git a/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.ts b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.ts new file mode 100644 index 0000000000000..1cc45fdc1e981 --- /dev/null +++ b/solution/2800-2899/2827.Number of Beautiful Integers in the Range/Solution.ts @@ -0,0 +1,59 @@ +function numberOfBeautifulIntegers( + low: number, + high: number, + k: number, +): number { + let s = String(high); + let f: number[][][] = Array(11) + .fill(0) + .map(() => + Array(21) + .fill(0) + .map(() => Array(21).fill(-1)), + ); + const dfs = ( + pos: number, + mod: number, + diff: number, + lead: boolean, + limit: boolean, + ): number => { + if (pos >= s.length) { + return mod == 0 && diff == 10 ? 1 : 0; + } + if (!lead && !limit && f[pos][mod][diff] != -1) { + return f[pos][mod][diff]; + } + let ans = 0; + const up = limit ? Number(s[pos]) : 9; + for (let i = 0; i <= up; ++i) { + if (i === 0 && lead) { + ans += dfs(pos + 1, mod, diff, true, limit && i === up); + } else { + const nxt = diff + (i % 2 ? 1 : -1); + ans += dfs( + pos + 1, + (mod * 10 + i) % k, + nxt, + false, + limit && i === up, + ); + } + } + if (!lead && !limit) { + f[pos][mod][diff] = ans; + } + return ans; + }; + const a = dfs(0, 0, 10, true, true); + s = String(low - 1); + f = Array(11) + .fill(0) + .map(() => + Array(21) + .fill(0) + .map(() => Array(21).fill(-1)), + ); + const b = dfs(0, 0, 10, true, true); + return a - b; +} diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README.md b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README.md new file mode 100644 index 0000000000000..4929bce998be1 --- /dev/null +++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README.md @@ -0,0 +1,134 @@ +# [2828. 判别首字母缩略词](https://leetcode.cn/problems/check-if-a-string-is-an-acronym-of-words) + +[English Version](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +<p>给你一个字符串数组 <code>words</code> 和一个字符串 <code>s</code> ,请你判断 <code>s</code> 是不是 <code>words</code> 的 <strong>首字母缩略词</strong> 。</p> + +<p>如果可以按顺序串联 <code>words</code> 中每个字符串的第一个字符形成字符串 <code>s</code> ,则认为 <code>s</code> 是 <code>words</code> 的首字母缩略词。例如,<code>"ab"</code> 可以由 <code>["apple", "banana"]</code> 形成,但是无法从 <code>["bear", "aardvark"]</code> 形成。</p> + +<p>如果 <code>s</code> 是 <code>words</code> 的首字母缩略词,返回 <code>true</code><em> </em>;否则,返回<em> </em><code>false</code> 。</p> + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<strong>输入:</strong>words = ["alice","bob","charlie"], s = "abc" +<strong>输出:</strong>true +<strong>解释:</strong>words 中 "alice"、"bob" 和 "charlie" 的第一个字符分别是 'a'、'b' 和 'c'。因此,s = "abc" 是首字母缩略词。 +</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<strong>输入:</strong>words = ["an","apple"], s = "a" +<strong>输出:</strong>false +<strong>解释:</strong>words 中 "an" 和 "apple" 的第一个字符分别是 'a' 和 'a'。 +串联这些字符形成的首字母缩略词是 "aa" 。 +因此,s = "a" 不是首字母缩略词。 +</pre> + +<p><strong class="example">示例 3:</strong></p> + +<pre> +<strong>输入:</strong>words = ["never","gonna","give","up","on","you"], s = "ngguoy" +<strong>输出:</strong>true +<strong>解释:</strong>串联数组 words 中每个字符串的第一个字符,得到字符串 "ngguoy" 。 +因此,s = "ngguoy" 是首字母缩略词。 +</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>1 <= words.length <= 100</code></li> + <li><code>1 <= words[i].length <= 10</code></li> + <li><code>1 <= s.length <= 100</code></li> + <li><code>words[i]</code> 和 <code>s</code> 由小写英文字母组成</li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:模拟** + +我们可以遍历数组 $words$ 中的每个字符串,将其首字母拼接起来,得到一个新的字符串 $t$,然后判断 $t$ 是否等于 $s$ 即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $words$ 的长度。 + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def isAcronym(self, words: List[str], s: str) -> bool: + return "".join(w[0] for w in words) == s +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + public boolean isAcronym(List<String> words, String s) { + StringBuilder t = new StringBuilder(); + for (var w : words) { + t.append(w.charAt(0)); + } + return t.toString().equals(s); + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + bool isAcronym(vector<string>& words, string s) { + string t; + for (auto& w : words) { + t += w[0]; + } + return t == s; + } +}; +``` + +### **Go** + +```go +func isAcronym(words []string, s string) bool { + t := []byte{} + for _, w := range words { + t = append(t, w[0]) + } + return string(t) == s +} +``` + +### **TypeScript** + +```ts +function isAcronym(words: string[], s: string): boolean { + return words.map(w => w[0]).join('') === s; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README_EN.md b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README_EN.md new file mode 100644 index 0000000000000..9304b5dddcaae --- /dev/null +++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/README_EN.md @@ -0,0 +1,118 @@ +# [2828. Check if a String Is an Acronym of Words](https://leetcode.com/problems/check-if-a-string-is-an-acronym-of-words) + +[中文文档](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README.md) + +## Description + +<p>Given an array of strings <code>words</code> and a string <code>s</code>, determine if <code>s</code> is an <strong>acronym</strong> of words.</p> + +<p>The string <code>s</code> is considered an acronym of <code>words</code> if it can be formed by concatenating the <strong>first</strong> character of each string in <code>words</code> <strong>in order</strong>. For example, <code>"ab"</code> can be formed from <code>["apple", "banana"]</code>, but it can't be formed from <code>["bear", "aardvark"]</code>.</p> + +<p>Return <code>true</code><em> if </em><code>s</code><em> is an acronym of </em><code>words</code><em>, and </em><code>false</code><em> otherwise. </em></p> + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> words = ["alice","bob","charlie"], s = "abc" +<strong>Output:</strong> true +<strong>Explanation:</strong> The first character in the words "alice", "bob", and "charlie" are 'a', 'b', and 'c', respectively. Hence, s = "abc" is the acronym. +</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> words = ["an","apple"], s = "a" +<strong>Output:</strong> false +<strong>Explanation:</strong> The first character in the words "an" and "apple" are 'a' and 'a', respectively. +The acronym formed by concatenating these characters is "aa". +Hence, s = "a" is not the acronym. +</pre> + +<p><strong class="example">Example 3:</strong></p> + +<pre> +<strong>Input:</strong> words = ["never","gonna","give","up","on","you"], s = "ngguoy" +<strong>Output:</strong> true +<strong>Explanation: </strong>By concatenating the first character of the words in the array, we get the string "ngguoy". +Hence, s = "ngguoy" is the acronym. +</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>1 <= words.length <= 100</code></li> + <li><code>1 <= words[i].length <= 10</code></li> + <li><code>1 <= s.length <= 100</code></li> + <li><code>words[i]</code> and <code>s</code> consist of lowercase English letters.</li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def isAcronym(self, words: List[str], s: str) -> bool: + return "".join(w[0] for w in words) == s +``` + +### **Java** + +```java +class Solution { + public boolean isAcronym(List<String> words, String s) { + StringBuilder t = new StringBuilder(); + for (var w : words) { + t.append(w.charAt(0)); + } + return t.toString().equals(s); + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + bool isAcronym(vector<string>& words, string s) { + string t; + for (auto& w : words) { + t += w[0]; + } + return t == s; + } +}; +``` + +### **Go** + +```go +func isAcronym(words []string, s string) bool { + t := []byte{} + for _, w := range words { + t = append(t, w[0]) + } + return string(t) == s +} +``` + +### **TypeScript** + +```ts +function isAcronym(words: string[], s: string): boolean { + return words.map(w => w[0]).join('') === s; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.cpp b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.cpp new file mode 100644 index 0000000000000..eda07254e5097 --- /dev/null +++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.cpp @@ -0,0 +1,10 @@ +class Solution { +public: + bool isAcronym(vector<string>& words, string s) { + string t; + for (auto& w : words) { + t += w[0]; + } + return t == s; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.go b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.go new file mode 100644 index 0000000000000..5c562df36c0b7 --- /dev/null +++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.go @@ -0,0 +1,7 @@ +func isAcronym(words []string, s string) bool { + t := []byte{} + for _, w := range words { + t = append(t, w[0]) + } + return string(t) == s +} \ No newline at end of file diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.java b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.java new file mode 100644 index 0000000000000..627c1d33530ad --- /dev/null +++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.java @@ -0,0 +1,9 @@ +class Solution { + public boolean isAcronym(List<String> words, String s) { + StringBuilder t = new StringBuilder(); + for (var w : words) { + t.append(w.charAt(0)); + } + return t.toString().equals(s); + } +} \ No newline at end of file diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.py b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.py new file mode 100644 index 0000000000000..3337eb558751d --- /dev/null +++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.py @@ -0,0 +1,3 @@ +class Solution: + def isAcronym(self, words: List[str], s: str) -> bool: + return "".join(w[0] for w in words) == s diff --git a/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.ts b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.ts new file mode 100644 index 0000000000000..a1ef3f8a24b8d --- /dev/null +++ b/solution/2800-2899/2828.Check if a String Is an Acronym of Words/Solution.ts @@ -0,0 +1,3 @@ +function isAcronym(words: string[], s: string): boolean { + return words.map(w => w[0]).join('') === s; +} diff --git a/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/README.md b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/README.md new file mode 100644 index 0000000000000..54b098ebfdf2d --- /dev/null +++ b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/README.md @@ -0,0 +1,168 @@ +# [2829. k-avoiding 数组的最小总和](https://leetcode.cn/problems/determine-the-minimum-sum-of-a-k-avoiding-array) + +[English Version](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +<p>给你两个整数 <code>n</code> 和 <code>k</code> 。</p> + +<p>对于一个由 <strong>不同</strong> 正整数组成的数组,如果其中不存在任何求和等于 k 的不同元素对,则称其为 <strong>k-avoiding</strong> 数组。</p> + +<p>返回长度为 <code>n</code> 的 <strong>k-avoiding</strong> 数组的可能的最小总和。</p> + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<strong>输入:</strong>n = 5, k = 4 +<strong>输出:</strong>18 +<strong>解释:</strong>设若 k-avoiding 数组为 [1,2,4,5,6] ,其元素总和为 18 。 +可以证明不存在总和小于 18 的 k-avoiding 数组。 +</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<strong>输入:</strong>n = 2, k = 6 +<strong>输出:</strong>3 +<strong>解释:</strong>可以构造数组 [1,2] ,其元素总和为 3 。 +可以证明不存在总和小于 3 的 k-avoiding 数组。 +</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>1 <= n, k <= 50</code></li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:贪心 + 模拟** + +我们从正整数 $i=1$ 开始,依次判断 $i$ 是否可以加入数组中,如果可以加入,则将 $i$ 加入数组中,累加到答案中,然后将 $k-i$ 置为已访问,表示 $k-i$ 不能加入数组中。循环直到数组长度为 $n$。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组长度。 + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def minimumSum(self, n: int, k: int) -> int: + s, i = 0, 1 + vis = set() + for _ in range(n): + while i in vis: + i += 1 + vis.add(i) + vis.add(k - i) + s += i + return s +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + public int minimumSum(int n, int k) { + int s = 0, i = 1; + boolean[] vis = new boolean[k + n * n + 1]; + while (n-- > 0) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minimumSum(int n, int k) { + int s = 0, i = 1; + bool vis[k + n * n + 1]; + memset(vis, false, sizeof(vis)); + while (n--) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; + } +}; +``` + +### **Go** + +```go +func minimumSum(n int, k int) int { + s, i := 0, 1 + vis := make([]bool, k+n*n+1) + for ; n > 0; n-- { + for vis[i] { + i++ + } + vis[i] = true + if k >= i { + vis[k-i] = true + } + s += i + } + return s +} +``` + +### **TypeScript** + +```ts +function minimumSum(n: number, k: number): number { + let s = 0; + let i = 1; + const vis: boolean[] = Array(n * n + k + 1); + while (n--) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/README_EN.md b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/README_EN.md new file mode 100644 index 0000000000000..179e4c900bc1b --- /dev/null +++ b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/README_EN.md @@ -0,0 +1,152 @@ +# [2829. Determine the Minimum Sum of a k-avoiding Array](https://leetcode.com/problems/determine-the-minimum-sum-of-a-k-avoiding-array) + +[中文文档](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README.md) + +## Description + +<p>You are given two integers, <code>n</code> and <code>k</code>.</p> + +<p>An array of <strong>distinct</strong> positive integers is called a <b>k-avoiding</b> array if there does not exist any pair of distinct elements that sum to <code>k</code>.</p> + +<p>Return <em>the <strong>minimum</strong> possible sum of a k-avoiding array of length </em><code>n</code>.</p> + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> n = 5, k = 4 +<strong>Output:</strong> 18 +<strong>Explanation:</strong> Consider the k-avoiding array [1,2,4,5,6], which has a sum of 18. +It can be proven that there is no k-avoiding array with a sum less than 18. +</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> n = 2, k = 6 +<strong>Output:</strong> 3 +<strong>Explanation:</strong> We can construct the array [1,2], which has a sum of 3. +It can be proven that there is no k-avoiding array with a sum less than 3. +</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>1 <= n, k <= 50</code></li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def minimumSum(self, n: int, k: int) -> int: + s, i = 0, 1 + vis = set() + for _ in range(n): + while i in vis: + i += 1 + vis.add(i) + vis.add(k - i) + s += i + return s +``` + +### **Java** + +```java +class Solution { + public int minimumSum(int n, int k) { + int s = 0, i = 1; + boolean[] vis = new boolean[k + n * n + 1]; + while (n-- > 0) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minimumSum(int n, int k) { + int s = 0, i = 1; + bool vis[k + n * n + 1]; + memset(vis, false, sizeof(vis)); + while (n--) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; + } +}; +``` + +### **Go** + +```go +func minimumSum(n int, k int) int { + s, i := 0, 1 + vis := make([]bool, k+n*n+1) + for ; n > 0; n-- { + for vis[i] { + i++ + } + vis[i] = true + if k >= i { + vis[k-i] = true + } + s += i + } + return s +} +``` + +### **TypeScript** + +```ts +function minimumSum(n: number, k: number): number { + let s = 0; + let i = 1; + const vis: boolean[] = Array(n * n + k + 1); + while (n--) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.cpp b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.cpp new file mode 100644 index 0000000000000..b9602dd6233f1 --- /dev/null +++ b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + int minimumSum(int n, int k) { + int s = 0, i = 1; + bool vis[k + n * n + 1]; + memset(vis, false, sizeof(vis)); + while (n--) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.go b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.go new file mode 100644 index 0000000000000..3ceacec441460 --- /dev/null +++ b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.go @@ -0,0 +1,15 @@ +func minimumSum(n int, k int) int { + s, i := 0, 1 + vis := make([]bool, k+n*n+1) + for ; n > 0; n-- { + for vis[i] { + i++ + } + vis[i] = true + if k >= i { + vis[k-i] = true + } + s += i + } + return s +} \ No newline at end of file diff --git a/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.java b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.java new file mode 100644 index 0000000000000..73a2284dad786 --- /dev/null +++ b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.java @@ -0,0 +1,17 @@ +class Solution { + public int minimumSum(int n, int k) { + int s = 0, i = 1; + boolean[] vis = new boolean[k + n * n + 1]; + while (n-- > 0) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.py b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.py new file mode 100644 index 0000000000000..4594f3166f2fa --- /dev/null +++ b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.py @@ -0,0 +1,11 @@ +class Solution: + def minimumSum(self, n: int, k: int) -> int: + s, i = 0, 1 + vis = set() + for _ in range(n): + while i in vis: + i += 1 + vis.add(i) + vis.add(k - i) + s += i + return s diff --git a/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.ts b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.ts new file mode 100644 index 0000000000000..75407c9881b83 --- /dev/null +++ b/solution/2800-2899/2829.Determine the Minimum Sum of a k-avoiding Array/Solution.ts @@ -0,0 +1,16 @@ +function minimumSum(n: number, k: number): number { + let s = 0; + let i = 1; + const vis: boolean[] = Array(n * n + k + 1); + while (n--) { + while (vis[i]) { + ++i; + } + vis[i] = true; + if (k >= i) { + vis[k - i] = true; + } + s += i; + } + return s; +} diff --git a/solution/2800-2899/2830.Maximize the Profit as the Salesman/README.md b/solution/2800-2899/2830.Maximize the Profit as the Salesman/README.md new file mode 100644 index 0000000000000..e8ff6dddcc507 --- /dev/null +++ b/solution/2800-2899/2830.Maximize the Profit as the Salesman/README.md @@ -0,0 +1,207 @@ +# [2830. 销售利润最大化](https://leetcode.cn/problems/maximize-the-profit-as-the-salesman) + +[English Version](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +<p>给你一个整数 <code>n</code> 表示数轴上的房屋数量,编号从 <code>0</code> 到 <code>n - 1</code> 。</p> + +<p>另给你一个二维整数数组 <code>offers</code> ,其中 <code>offers[i] = [start<sub>i</sub>, end<sub>i</sub>, gold<sub>i</sub>]</code> 表示第 <code>i</code> 个买家想要以 <code>gold<sub>i</sub></code> 枚金币的价格购买从 <code>start<sub>i</sub></code> 到 <code>end<sub>i</sub></code> 的所有房屋。</p> + +<p>作为一名销售,你需要有策略地选择并销售房屋使自己的收入最大化。</p> + +<p>返回你可以赚取的金币的最大数目。</p> + +<p><strong>注意</strong> 同一所房屋不能卖给不同的买家,并且允许保留一些房屋不进行出售。</p> + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<strong>输入:</strong>n = 5, offers = [[0,0,1],[0,2,2],[1,3,2]] +<strong>输出:</strong>3 +<strong>解释:</strong> +有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。 +将位于 [0,0] 范围内的房屋以 1 金币的价格出售给第 1 位买家,并将位于 [1,3] 范围内的房屋以 2 金币的价格出售给第 3 位买家。 +可以证明我们最多只能获得 3 枚金币。</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<strong>输入:</strong>n = 5, offers = [[0,0,1],[0,2,10],[1,3,2]] +<strong>输出:</strong>10 +<strong>解释:</strong>有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。 +将位于 [0,2] 范围内的房屋以 10 金币的价格出售给第 2 位买家。 +可以证明我们最多只能获得 10 枚金币。</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>1 <= n <= 10<sup>5</sup></code></li> + <li><code>1 <= offers.length <= 10<sup>5</sup></code></li> + <li><code>offers[i].length == 3</code></li> + <li><code>0 <= start<sub>i</sub> <= end<sub>i</sub> <= n - 1</code></li> + <li><code>1 <= gold<sub>i</sub> <= 10<sup>3</sup></code></li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:排序 + 二分查找 + 动态规划** + +我们将所有的购买要约按照 $end$ 从小到大排序,然后使用动态规划求解。 + +定义 $f[i]$ 表示前 $i$ 个购买要约中,我们可以获得的最大金币数。答案即为 $f[n]$。 + +对于 $f[i]$,我们可以选择不卖出第 $i$ 个购买要约,此时 $f[i] = f[i - 1]$;也可以选择卖出第 $i$ 个购买要约,此时 $f[i] = f[j] + gold_i$,其中 $j$ 是满足 $end_j \leq start_i$ 的最大下标。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是购买要约的数量。 + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def maximizeTheProfit(self, n: int, offers: List[List[int]]) -> int: + offers.sort(key=lambda x: x[1]) + f = [0] * (len(offers) + 1) + g = [x[1] for x in offers] + for i, (s, _, v) in enumerate(offers, 1): + j = bisect_left(g, s) + f[i] = max(f[i - 1], f[j] + v) + return f[-1] +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + public int maximizeTheProfit(int n, List<List<Integer>> offers) { + offers.sort((a, b) -> a.get(1) - b.get(1)); + n = offers.size(); + int[] f = new int[n + 1]; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + g[i] = offers.get(i).get(1); + } + for (int i = 1; i <= n; ++i) { + var o = offers.get(i - 1); + int j = search(g, o.get(0)); + f[i] = Math.max(f[i - 1], f[j] + o.get(2)); + } + return f[n]; + } + + private int search(int[] nums, int x) { + int l = 0, r = nums.length; + while (l < r) { + int mid = (l + r) >> 1; + if (nums[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int maximizeTheProfit(int n, vector<vector<int>>& offers) { + sort(offers.begin(), offers.end(), [](const vector<int>& a, const vector<int>& b) { + return a[1] < b[1]; + }); + n = offers.size(); + vector<int> f(n + 1); + vector<int> g; + for (auto& o : offers) { + g.push_back(o[1]); + } + for (int i = 1; i <= n; ++i) { + auto o = offers[i - 1]; + int j = lower_bound(g.begin(), g.end(), o[0]) - g.begin(); + f[i] = max(f[i - 1], f[j] + o[2]); + } + return f[n]; + } +}; +``` + +### **Go** + +```go +func maximizeTheProfit(n int, offers [][]int) int { + sort.Slice(offers, func(i, j int) bool { return offers[i][1] < offers[j][1] }) + n = len(offers) + f := make([]int, n+1) + g := []int{} + for _, o := range offers { + g = append(g, o[1]) + } + for i := 1; i <= n; i++ { + j := sort.SearchInts(g, offers[i-1][0]) + f[i] = max(f[i-1], f[j]+offers[i-1][2]) + } + return f[n] +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function maximizeTheProfit(n: number, offers: number[][]): number { + offers.sort((a, b) => a[1] - b[1]); + n = offers.length; + const f: number[] = Array(n + 1).fill(0); + const g = offers.map(x => x[1]); + const search = (x: number) => { + let l = 0; + let r = n; + while (l < r) { + const mid = (l + r) >> 1; + if (g[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + for (let i = 1; i <= n; ++i) { + const j = search(offers[i - 1][0]); + f[i] = Math.max(f[i - 1], f[j] + offers[i - 1][2]); + } + return f[n]; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2830.Maximize the Profit as the Salesman/README_EN.md b/solution/2800-2899/2830.Maximize the Profit as the Salesman/README_EN.md new file mode 100644 index 0000000000000..0bb318b1112fb --- /dev/null +++ b/solution/2800-2899/2830.Maximize the Profit as the Salesman/README_EN.md @@ -0,0 +1,188 @@ +# [2830. Maximize the Profit as the Salesman](https://leetcode.com/problems/maximize-the-profit-as-the-salesman) + +[中文文档](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README.md) + +## Description + +<p>You are given an integer <code>n</code> representing the number of houses on a number line, numbered from <code>0</code> to <code>n - 1</code>.</p> + +<p>Additionally, you are given a 2D integer array <code>offers</code> where <code>offers[i] = [start<sub>i</sub>, end<sub>i</sub>, gold<sub>i</sub>]</code>, indicating that <code>i<sup>th</sup></code> buyer wants to buy all the houses from <code>start<sub>i</sub></code> to <code>end<sub>i</sub></code> for <code>gold<sub>i</sub></code> amount of gold.</p> + +<p>As a salesman, your goal is to <strong>maximize</strong> your earnings by strategically selecting and selling houses to buyers.</p> + +<p>Return <em>the maximum amount of gold you can earn</em>.</p> + +<p><strong>Note</strong> that different buyers can't buy the same house, and some houses may remain unsold.</p> + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> n = 5, offers = [[0,0,1],[0,2,2],[1,3,2]] +<strong>Output:</strong> 3 +<strong>Explanation:</strong> There are 5 houses numbered from 0 to 4 and there are 3 purchase offers. +We sell houses in the range [0,0] to 1<sup>st</sup> buyer for 1 gold and houses in the range [1,3] to 3<sup>rd</sup> buyer for 2 golds. +It can be proven that 3 is the maximum amount of gold we can achieve. +</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> n = 5, offers = [[0,0,1],[0,2,10],[1,3,2]] +<strong>Output:</strong> 10 +<strong>Explanation:</strong> There are 5 houses numbered from 0 to 4 and there are 3 purchase offers. +We sell houses in the range [0,2] to 2<sup>nd</sup> buyer for 10 golds. +It can be proven that 10 is the maximum amount of gold we can achieve. +</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>1 <= n <= 10<sup>5</sup></code></li> + <li><code>1 <= offers.length <= 10<sup>5</sup></code></li> + <li><code>offers[i].length == 3</code></li> + <li><code>0 <= start<sub>i</sub> <= end<sub>i</sub> <= n - 1</code></li> + <li><code>1 <= gold<sub>i</sub> <= 10<sup>3</sup></code></li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def maximizeTheProfit(self, n: int, offers: List[List[int]]) -> int: + offers.sort(key=lambda x: x[1]) + f = [0] * (len(offers) + 1) + g = [x[1] for x in offers] + for i, (s, _, v) in enumerate(offers, 1): + j = bisect_left(g, s) + f[i] = max(f[i - 1], f[j] + v) + return f[-1] +``` + +### **Java** + +```java +class Solution { + public int maximizeTheProfit(int n, List<List<Integer>> offers) { + offers.sort((a, b) -> a.get(1) - b.get(1)); + n = offers.size(); + int[] f = new int[n + 1]; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + g[i] = offers.get(i).get(1); + } + for (int i = 1; i <= n; ++i) { + var o = offers.get(i - 1); + int j = search(g, o.get(0)); + f[i] = Math.max(f[i - 1], f[j] + o.get(2)); + } + return f[n]; + } + + private int search(int[] nums, int x) { + int l = 0, r = nums.length; + while (l < r) { + int mid = (l + r) >> 1; + if (nums[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int maximizeTheProfit(int n, vector<vector<int>>& offers) { + sort(offers.begin(), offers.end(), [](const vector<int>& a, const vector<int>& b) { + return a[1] < b[1]; + }); + n = offers.size(); + vector<int> f(n + 1); + vector<int> g; + for (auto& o : offers) { + g.push_back(o[1]); + } + for (int i = 1; i <= n; ++i) { + auto o = offers[i - 1]; + int j = lower_bound(g.begin(), g.end(), o[0]) - g.begin(); + f[i] = max(f[i - 1], f[j] + o[2]); + } + return f[n]; + } +}; +``` + +### **Go** + +```go +func maximizeTheProfit(n int, offers [][]int) int { + sort.Slice(offers, func(i, j int) bool { return offers[i][1] < offers[j][1] }) + n = len(offers) + f := make([]int, n+1) + g := []int{} + for _, o := range offers { + g = append(g, o[1]) + } + for i := 1; i <= n; i++ { + j := sort.SearchInts(g, offers[i-1][0]) + f[i] = max(f[i-1], f[j]+offers[i-1][2]) + } + return f[n] +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function maximizeTheProfit(n: number, offers: number[][]): number { + offers.sort((a, b) => a[1] - b[1]); + n = offers.length; + const f: number[] = Array(n + 1).fill(0); + const g = offers.map(x => x[1]); + const search = (x: number) => { + let l = 0; + let r = n; + while (l < r) { + const mid = (l + r) >> 1; + if (g[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + for (let i = 1; i <= n; ++i) { + const j = search(offers[i - 1][0]); + f[i] = Math.max(f[i - 1], f[j] + offers[i - 1][2]); + } + return f[n]; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.cpp b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.cpp new file mode 100644 index 0000000000000..56432462a47b4 --- /dev/null +++ b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.cpp @@ -0,0 +1,20 @@ +class Solution { +public: + int maximizeTheProfit(int n, vector<vector<int>>& offers) { + sort(offers.begin(), offers.end(), [](const vector<int>& a, const vector<int>& b) { + return a[1] < b[1]; + }); + n = offers.size(); + vector<int> f(n + 1); + vector<int> g; + for (auto& o : offers) { + g.push_back(o[1]); + } + for (int i = 1; i <= n; ++i) { + auto o = offers[i - 1]; + int j = lower_bound(g.begin(), g.end(), o[0]) - g.begin(); + f[i] = max(f[i - 1], f[j] + o[2]); + } + return f[n]; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.go b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.go new file mode 100644 index 0000000000000..8fb8dbd90a28c --- /dev/null +++ b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.go @@ -0,0 +1,21 @@ +func maximizeTheProfit(n int, offers [][]int) int { + sort.Slice(offers, func(i, j int) bool { return offers[i][1] < offers[j][1] }) + n = len(offers) + f := make([]int, n+1) + g := []int{} + for _, o := range offers { + g = append(g, o[1]) + } + for i := 1; i <= n; i++ { + j := sort.SearchInts(g, offers[i-1][0]) + f[i] = max(f[i-1], f[j]+offers[i-1][2]) + } + return f[n] +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} \ No newline at end of file diff --git a/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.java b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.java new file mode 100644 index 0000000000000..5826122dce9ea --- /dev/null +++ b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.java @@ -0,0 +1,30 @@ +class Solution { + public int maximizeTheProfit(int n, List<List<Integer>> offers) { + offers.sort((a, b) -> a.get(1) - b.get(1)); + n = offers.size(); + int[] f = new int[n + 1]; + int[] g = new int[n]; + for (int i = 0; i < n; ++i) { + g[i] = offers.get(i).get(1); + } + for (int i = 1; i <= n; ++i) { + var o = offers.get(i - 1); + int j = search(g, o.get(0)); + f[i] = Math.max(f[i - 1], f[j] + o.get(2)); + } + return f[n]; + } + + private int search(int[] nums, int x) { + int l = 0, r = nums.length; + while (l < r) { + int mid = (l + r) >> 1; + if (nums[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.py b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.py new file mode 100644 index 0000000000000..6f7eeb04aaa58 --- /dev/null +++ b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.py @@ -0,0 +1,9 @@ +class Solution: + def maximizeTheProfit(self, n: int, offers: List[List[int]]) -> int: + offers.sort(key=lambda x: x[1]) + f = [0] * (len(offers) + 1) + g = [x[1] for x in offers] + for i, (s, _, v) in enumerate(offers, 1): + j = bisect_left(g, s) + f[i] = max(f[i - 1], f[j] + v) + return f[-1] diff --git a/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.ts b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.ts new file mode 100644 index 0000000000000..53601c6dd7de7 --- /dev/null +++ b/solution/2800-2899/2830.Maximize the Profit as the Salesman/Solution.ts @@ -0,0 +1,24 @@ +function maximizeTheProfit(n: number, offers: number[][]): number { + offers.sort((a, b) => a[1] - b[1]); + n = offers.length; + const f: number[] = Array(n + 1).fill(0); + const g = offers.map(x => x[1]); + const search = (x: number) => { + let l = 0; + let r = n; + while (l < r) { + const mid = (l + r) >> 1; + if (g[mid] >= x) { + r = mid; + } else { + l = mid + 1; + } + } + return l; + }; + for (let i = 1; i <= n; ++i) { + const j = search(offers[i - 1][0]); + f[i] = Math.max(f[i - 1], f[j] + offers[i - 1][2]); + } + return f[n]; +} diff --git a/solution/2800-2899/2831.Find the Longest Equal Subarray/README.md b/solution/2800-2899/2831.Find the Longest Equal Subarray/README.md new file mode 100644 index 0000000000000..eff9106ec3698 --- /dev/null +++ b/solution/2800-2899/2831.Find the Longest Equal Subarray/README.md @@ -0,0 +1,178 @@ +# [2831. 找出最长等值子数组](https://leetcode.cn/problems/find-the-longest-equal-subarray) + +[English Version](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README_EN.md) + +## 题目描述 + +<!-- 这里写题目描述 --> + +<p>给你一个下标从 <strong>0</strong> 开始的整数数组 <code>nums</code> 和一个整数 <code>k</code> 。</p> + +<p>如果子数组中所有元素都相等,则认为子数组是一个 <strong>等值子数组</strong> 。注意,空数组是 <strong>等值子数组</strong> 。</p> + +<p>从 <code>nums</code> 中删除最多 <code>k</code> 个元素后,返回可能的最长等值子数组的长度。</p> + +<p><strong>子数组</strong> 是数组中一个连续且可能为空的元素序列。</p> + +<p> </p> + +<p><strong class="example">示例 1:</strong></p> + +<pre> +<strong>输入:</strong>nums = [1,3,2,3,1,3], k = 3 +<strong>输出:</strong>3 +<strong>解释:</strong>最优的方案是删除下标 2 和下标 4 的元素。 +删除后,nums 等于 [1, 3, 3, 3] 。 +最长等值子数组从 i = 1 开始到 j = 3 结束,长度等于 3 。 +可以证明无法创建更长的等值子数组。 +</pre> + +<p><strong class="example">示例 2:</strong></p> + +<pre> +<strong>输入:</strong>nums = [1,1,2,2,1,1], k = 2 +<strong>输出:</strong>4 +<strong>解释:</strong>最优的方案是删除下标 2 和下标 3 的元素。 +删除后,nums 等于 [1, 1, 1, 1] 。 +数组自身就是等值子数组,长度等于 4 。 +可以证明无法创建更长的等值子数组。 +</pre> + +<p> </p> + +<p><strong>提示:</strong></p> + +<ul> + <li><code>1 <= nums.length <= 10<sup>5</sup></code></li> + <li><code>1 <= nums[i] <= nums.length</code></li> + <li><code>0 <= k <= nums.length</code></li> +</ul> + +## 解法 + +<!-- 这里可写通用的实现逻辑 --> + +**方法一:哈希表 + 双指针** + +我们用双指针维护一个单调变长的窗口,用哈希表维护窗口中每个元素出现的次数。 + +窗口中的所有元素个数减去窗口中出现次数最多的元素个数,就是窗口中需要删除的元素个数。 + +每一次,我们将右指针指向的元素加入窗口,然后更新哈希表,同时更新窗口中出现次数最多的元素个数。当窗口中需要删除的元素个数超过了 $k$ 时,我们就移动一次左指针,然后更新哈希表。 + +遍历结束后,返回出现次数最多的元素个数即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。 + +<!-- tabs:start --> + +### **Python3** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```python +class Solution: + def longestEqualSubarray(self, nums: List[int], k: int) -> int: + cnt = Counter() + l = 0 + mx = 0 + for r, x in enumerate(nums): + cnt[x] += 1 + mx = max(mx, cnt[x]) + if r - l + 1 - mx > k: + cnt[nums[l]] -= 1 + l += 1 + return mx +``` + +### **Java** + +<!-- 这里可写当前语言的特殊实现逻辑 --> + +```java +class Solution { + public int longestEqualSubarray(List<Integer> nums, int k) { + Map<Integer, Integer> cnt = new HashMap<>(); + int mx = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + cnt.merge(nums.get(r), 1, Integer::sum); + mx = Math.max(mx, cnt.get(nums.get(r))); + if (r - l + 1 - mx > k) { + cnt.merge(nums.get(l++), -1, Integer::sum); + } + } + return mx; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int longestEqualSubarray(vector<int>& nums, int k) { + unordered_map<int, int> cnt; + int mx = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + mx = max(mx, ++cnt[nums[r]]); + if (r - l + 1 - mx > k) { + --cnt[nums[l++]]; + } + } + return mx; + } +}; +``` + +### **Go** + +```go +func longestEqualSubarray(nums []int, k int) int { + cnt := map[int]int{} + mx, l := 0, 0 + for r, x := range nums { + cnt[x]++ + mx = max(mx, cnt[x]) + if r-l+1-mx > k { + cnt[nums[l]]-- + l++ + } + } + return mx +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function longestEqualSubarray(nums: number[], k: number): number { + const cnt: Map<number, number> = new Map(); + let mx = 0; + let l = 0; + for (let r = 0; r < nums.length; ++r) { + cnt.set(nums[r], (cnt.get(nums[r]) ?? 0) + 1); + mx = Math.max(mx, cnt.get(nums[r])!); + if (r - l + 1 - mx > k) { + cnt.set(nums[l], cnt.get(nums[l])! - 1); + ++l; + } + } + return mx; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2831.Find the Longest Equal Subarray/README_EN.md b/solution/2800-2899/2831.Find the Longest Equal Subarray/README_EN.md new file mode 100644 index 0000000000000..8b56b55842359 --- /dev/null +++ b/solution/2800-2899/2831.Find the Longest Equal Subarray/README_EN.md @@ -0,0 +1,156 @@ +# [2831. Find the Longest Equal Subarray](https://leetcode.com/problems/find-the-longest-equal-subarray) + +[中文文档](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README.md) + +## Description + +<p>You are given a <strong>0-indexed</strong> integer array <code>nums</code> and an integer <code>k</code>.</p> + +<p>A subarray is called <strong>equal</strong> if all of its elements are equal. Note that the empty subarray is an <strong>equal</strong> subarray.</p> + +<p>Return <em>the length of the <strong>longest</strong> possible equal subarray after deleting <strong>at most</strong> </em><code>k</code><em> elements from </em><code>nums</code>.</p> + +<p>A <b>subarray</b> is a contiguous, possibly empty sequence of elements within an array.</p> + +<p> </p> +<p><strong class="example">Example 1:</strong></p> + +<pre> +<strong>Input:</strong> nums = [1,3,2,3,1,3], k = 3 +<strong>Output:</strong> 3 +<strong>Explanation:</strong> It's optimal to delete the elements at index 2 and index 4. +After deleting them, nums becomes equal to [1, 3, 3, 3]. +The longest equal subarray starts at i = 1 and ends at j = 3 with length equal to 3. +It can be proven that no longer equal subarrays can be created. +</pre> + +<p><strong class="example">Example 2:</strong></p> + +<pre> +<strong>Input:</strong> nums = [1,1,2,2,1,1], k = 2 +<strong>Output:</strong> 4 +<strong>Explanation:</strong> It's optimal to delete the elements at index 2 and index 3. +After deleting them, nums becomes equal to [1, 1, 1, 1]. +The array itself is an equal subarray, so the answer is 4. +It can be proven that no longer equal subarrays can be created. +</pre> + +<p> </p> +<p><strong>Constraints:</strong></p> + +<ul> + <li><code>1 <= nums.length <= 10<sup>5</sup></code></li> + <li><code>1 <= nums[i] <= nums.length</code></li> + <li><code>0 <= k <= nums.length</code></li> +</ul> + +## Solutions + +<!-- tabs:start --> + +### **Python3** + +```python +class Solution: + def longestEqualSubarray(self, nums: List[int], k: int) -> int: + cnt = Counter() + l = 0 + mx = 0 + for r, x in enumerate(nums): + cnt[x] += 1 + mx = max(mx, cnt[x]) + if r - l + 1 - mx > k: + cnt[nums[l]] -= 1 + l += 1 + return mx +``` + +### **Java** + +```java +class Solution { + public int longestEqualSubarray(List<Integer> nums, int k) { + Map<Integer, Integer> cnt = new HashMap<>(); + int mx = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + cnt.merge(nums.get(r), 1, Integer::sum); + mx = Math.max(mx, cnt.get(nums.get(r))); + if (r - l + 1 - mx > k) { + cnt.merge(nums.get(l++), -1, Integer::sum); + } + } + return mx; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int longestEqualSubarray(vector<int>& nums, int k) { + unordered_map<int, int> cnt; + int mx = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + mx = max(mx, ++cnt[nums[r]]); + if (r - l + 1 - mx > k) { + --cnt[nums[l++]]; + } + } + return mx; + } +}; +``` + +### **Go** + +```go +func longestEqualSubarray(nums []int, k int) int { + cnt := map[int]int{} + mx, l := 0, 0 + for r, x := range nums { + cnt[x]++ + mx = max(mx, cnt[x]) + if r-l+1-mx > k { + cnt[nums[l]]-- + l++ + } + } + return mx +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function longestEqualSubarray(nums: number[], k: number): number { + const cnt: Map<number, number> = new Map(); + let mx = 0; + let l = 0; + for (let r = 0; r < nums.length; ++r) { + cnt.set(nums[r], (cnt.get(nums[r]) ?? 0) + 1); + mx = Math.max(mx, cnt.get(nums[r])!); + if (r - l + 1 - mx > k) { + cnt.set(nums[l], cnt.get(nums[l])! - 1); + ++l; + } + } + return mx; +} +``` + +### **...** + +``` + +``` + +<!-- tabs:end --> diff --git a/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.cpp b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.cpp new file mode 100644 index 0000000000000..18272fa904d0f --- /dev/null +++ b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.cpp @@ -0,0 +1,14 @@ +class Solution { +public: + int longestEqualSubarray(vector<int>& nums, int k) { + unordered_map<int, int> cnt; + int mx = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + mx = max(mx, ++cnt[nums[r]]); + if (r - l + 1 - mx > k) { + --cnt[nums[l++]]; + } + } + return mx; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.go b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.go new file mode 100644 index 0000000000000..a9c74f51465fe --- /dev/null +++ b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.go @@ -0,0 +1,20 @@ +func longestEqualSubarray(nums []int, k int) int { + cnt := map[int]int{} + mx, l := 0, 0 + for r, x := range nums { + cnt[x]++ + mx = max(mx, cnt[x]) + if r-l+1-mx > k { + cnt[nums[l]]-- + l++ + } + } + return mx +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} \ No newline at end of file diff --git a/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.java b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.java new file mode 100644 index 0000000000000..e222a18aafc5d --- /dev/null +++ b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.java @@ -0,0 +1,14 @@ +class Solution { + public int longestEqualSubarray(List<Integer> nums, int k) { + Map<Integer, Integer> cnt = new HashMap<>(); + int mx = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + cnt.merge(nums.get(r), 1, Integer::sum); + mx = Math.max(mx, cnt.get(nums.get(r))); + if (r - l + 1 - mx > k) { + cnt.merge(nums.get(l++), -1, Integer::sum); + } + } + return mx; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.py b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.py new file mode 100644 index 0000000000000..47a7b6013d0e6 --- /dev/null +++ b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.py @@ -0,0 +1,12 @@ +class Solution: + def longestEqualSubarray(self, nums: List[int], k: int) -> int: + cnt = Counter() + l = 0 + mx = 0 + for r, x in enumerate(nums): + cnt[x] += 1 + mx = max(mx, cnt[x]) + if r - l + 1 - mx > k: + cnt[nums[l]] -= 1 + l += 1 + return mx diff --git a/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.ts b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.ts new file mode 100644 index 0000000000000..cb58a697d8c45 --- /dev/null +++ b/solution/2800-2899/2831.Find the Longest Equal Subarray/Solution.ts @@ -0,0 +1,14 @@ +function longestEqualSubarray(nums: number[], k: number): number { + const cnt: Map<number, number> = new Map(); + let mx = 0; + let l = 0; + for (let r = 0; r < nums.length; ++r) { + cnt.set(nums[r], (cnt.get(nums[r]) ?? 0) + 1); + mx = Math.max(mx, cnt.get(nums[r])!); + if (r - l + 1 - mx > k) { + cnt.set(nums[l], cnt.get(nums[l])! - 1); + ++l; + } + } + return mx; +} diff --git a/solution/CONTEST_README.md b/solution/CONTEST_README.md index b7fc38cdde040..52906c21d5dc9 100644 --- a/solution/CONTEST_README.md +++ b/solution/CONTEST_README.md @@ -22,6 +22,20 @@ ## 往期竞赛 +#### 第 359 场周赛(2023-08-20 10:30, 90 分钟) 参赛人数 4097 + +- [2828. 判别首字母缩略词](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README.md) +- [2829. k-avoiding 数组的最小总和](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README.md) +- [2830. 销售利润最大化](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README.md) +- [2831. 找出最长等值子数组](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README.md) + +#### 第 111 场双周赛(2023-08-19 22:30, 90 分钟) 参赛人数 2787 + +- [2824. 统计和小于目标的下标对数目](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README.md) +- [2825. 循环增长使字符串子序列等于另一个字符串](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README.md) +- [2826. 将三个组排序](/solution/2800-2899/2826.Sorting%20Three%20Groups/README.md) +- [2827. 范围中美丽整数的数目](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README.md) + #### 第 358 场周赛(2023-08-13 10:30, 90 分钟) 参赛人数 4475 - [2815. 数组中的最大数对和](/solution/2800-2899/2815.Max%20Pair%20Sum%20in%20an%20Array/README.md) diff --git a/solution/CONTEST_README_EN.md b/solution/CONTEST_README_EN.md index e43e47bff61a0..62bca35de9ba2 100644 --- a/solution/CONTEST_README_EN.md +++ b/solution/CONTEST_README_EN.md @@ -25,6 +25,20 @@ Get your rating changes right after the completion of LeetCode contests, https:/ ## Past Contests +#### Weekly Contest 359 + +- [2828. Check if a String Is an Acronym of Words](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README_EN.md) +- [2829. Determine the Minimum Sum of a k-avoiding Array](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README_EN.md) +- [2830. Maximize the Profit as the Salesman](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README_EN.md) +- [2831. Find the Longest Equal Subarray](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README_EN.md) + +#### Biweekly Contest 111 + +- [2824. Count Pairs Whose Sum is Less than Target](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README_EN.md) +- [2825. Make String a Subsequence Using Cyclic Increments](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README_EN.md) +- [2826. Sorting Three Groups](/solution/2800-2899/2826.Sorting%20Three%20Groups/README_EN.md) +- [2827. Number of Beautiful Integers in the Range](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README_EN.md) + #### Weekly Contest 358 - [2815. Max Pair Sum in an Array](/solution/2800-2899/2815.Max%20Pair%20Sum%20in%20an%20Array/README_EN.md) diff --git a/solution/README.md b/solution/README.md index 9971f5ca016c5..c05510b08b492 100644 --- a/solution/README.md +++ b/solution/README.md @@ -2834,6 +2834,14 @@ | 2821 | [延迟每个 Promise 对象的解析](/solution/2800-2899/2821.Delay%20the%20Resolution%20of%20Each%20Promise/README.md) | | 简单 | 🔒 | | 2822 | [对象反转](/solution/2800-2899/2822.Inversion%20of%20Object/README.md) | | 简单 | 🔒 | | 2823 | [深度对象筛选](/solution/2800-2899/2823.Deep%20Object%20Filter/README.md) | | 中等 | 🔒 | +| 2824 | [统计和小于目标的下标对数目](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README.md) | | 简单 | 第 111 场双周赛 | +| 2825 | [循环增长使字符串子序列等于另一个字符串](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README.md) | | 中等 | 第 111 场双周赛 | +| 2826 | [将三个组排序](/solution/2800-2899/2826.Sorting%20Three%20Groups/README.md) | | 中等 | 第 111 场双周赛 | +| 2827 | [范围中美丽整数的数目](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README.md) | | 困难 | 第 111 场双周赛 | +| 2828 | [判别首字母缩略词](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README.md) | | 简单 | 第 359 场周赛 | +| 2829 | [k-avoiding 数组的最小总和](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README.md) | | 中等 | 第 359 场周赛 | +| 2830 | [销售利润最大化](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README.md) | | 中等 | 第 359 场周赛 | +| 2831 | [找出最长等值子数组](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README.md) | | 中等 | 第 359 场周赛 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index 8af80d2f21c46..753e85c734714 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -2832,6 +2832,14 @@ Press <kbd>Control</kbd>+<kbd>F</kbd>(or <kbd>Command</kbd>+<kbd>F</kbd> on the | 2821 | [Delay the Resolution of Each Promise](/solution/2800-2899/2821.Delay%20the%20Resolution%20of%20Each%20Promise/README_EN.md) | | Easy | 🔒 | | 2822 | [Inversion of Object](/solution/2800-2899/2822.Inversion%20of%20Object/README_EN.md) | | Easy | 🔒 | | 2823 | [Deep Object Filter](/solution/2800-2899/2823.Deep%20Object%20Filter/README_EN.md) | | Medium | 🔒 | +| 2824 | [Count Pairs Whose Sum is Less than Target](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README_EN.md) | | Easy | Biweekly Contest 111 | +| 2825 | [Make String a Subsequence Using Cyclic Increments](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README_EN.md) | | Medium | Biweekly Contest 111 | +| 2826 | [Sorting Three Groups](/solution/2800-2899/2826.Sorting%20Three%20Groups/README_EN.md) | | Medium | Biweekly Contest 111 | +| 2827 | [Number of Beautiful Integers in the Range](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README_EN.md) | | Hard | Biweekly Contest 111 | +| 2828 | [Check if a String Is an Acronym of Words](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README_EN.md) | | Easy | Weekly Contest 359 | +| 2829 | [Determine the Minimum Sum of a k-avoiding Array](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README_EN.md) | | Medium | Weekly Contest 359 | +| 2830 | [Maximize the Profit as the Salesman](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README_EN.md) | | Medium | Weekly Contest 359 | +| 2831 | [Find the Longest Equal Subarray](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README_EN.md) | | Medium | Weekly Contest 359 | ## Copyright diff --git a/solution/summary.md b/solution/summary.md index 6965bf4206e44..cbd37684d52a3 100644 --- a/solution/summary.md +++ b/solution/summary.md @@ -2879,3 +2879,11 @@ - [2821.延迟每个 Promise 对象的解析](/solution/2800-2899/2821.Delay%20the%20Resolution%20of%20Each%20Promise/README.md) - [2822.对象反转](/solution/2800-2899/2822.Inversion%20of%20Object/README.md) - [2823.深度对象筛选](/solution/2800-2899/2823.Deep%20Object%20Filter/README.md) + - [2824.统计和小于目标的下标对数目](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README.md) + - [2825.循环增长使字符串子序列等于另一个字符串](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README.md) + - [2826.将三个组排序](/solution/2800-2899/2826.Sorting%20Three%20Groups/README.md) + - [2827.范围中美丽整数的数目](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README.md) + - [2828.判别首字母缩略词](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README.md) + - [2829.k-avoiding 数组的最小总和](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README.md) + - [2830.销售利润最大化](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README.md) + - [2831.找出最长等值子数组](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README.md) diff --git a/solution/summary_en.md b/solution/summary_en.md index 27fc4f74b1a68..a5010b0ffed77 100644 --- a/solution/summary_en.md +++ b/solution/summary_en.md @@ -2879,3 +2879,11 @@ - [2821.Delay the Resolution of Each Promise](/solution/2800-2899/2821.Delay%20the%20Resolution%20of%20Each%20Promise/README_EN.md) - [2822.Inversion of Object](/solution/2800-2899/2822.Inversion%20of%20Object/README_EN.md) - [2823.Deep Object Filter](/solution/2800-2899/2823.Deep%20Object%20Filter/README_EN.md) + - [2824.Count Pairs Whose Sum is Less than Target](/solution/2800-2899/2824.Count%20Pairs%20Whose%20Sum%20is%20Less%20than%20Target/README_EN.md) + - [2825.Make String a Subsequence Using Cyclic Increments](/solution/2800-2899/2825.Make%20String%20a%20Subsequence%20Using%20Cyclic%20Increments/README_EN.md) + - [2826.Sorting Three Groups](/solution/2800-2899/2826.Sorting%20Three%20Groups/README_EN.md) + - [2827.Number of Beautiful Integers in the Range](/solution/2800-2899/2827.Number%20of%20Beautiful%20Integers%20in%20the%20Range/README_EN.md) + - [2828.Check if a String Is an Acronym of Words](/solution/2800-2899/2828.Check%20if%20a%20String%20Is%20an%20Acronym%20of%20Words/README_EN.md) + - [2829.Determine the Minimum Sum of a k-avoiding Array](/solution/2800-2899/2829.Determine%20the%20Minimum%20Sum%20of%20a%20k-avoiding%20Array/README_EN.md) + - [2830.Maximize the Profit as the Salesman](/solution/2800-2899/2830.Maximize%20the%20Profit%20as%20the%20Salesman/README_EN.md) + - [2831.Find the Longest Equal Subarray](/solution/2800-2899/2831.Find%20the%20Longest%20Equal%20Subarray/README_EN.md)