From b58ef6cbbe310b0830ff0c44ea77f339f337af95 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 8 Aug 2025 07:11:56 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.3641 No.3641.Longest Semi-Repeating Subarray --- .../README.md | 2 + .../README_EN.md | 2 + .../README.md | 2 + .../README_EN.md | 2 + .../README.md | 2 + .../README_EN.md | 2 + .../3636.Threshold Majority Queries/README.md | 2 + .../README_EN.md | 2 + .../3600-3699/3637.Trionic Array I/README.md | 2 + .../3637.Trionic Array I/README_EN.md | 2 + .../3638.Maximum Balanced Shipments/README.md | 2 + .../README_EN.md | 2 + .../README.md | 2 + .../README_EN.md | 2 + .../3600-3699/3640.Trionic Array II/README.md | 2 + .../3640.Trionic Array II/README_EN.md | 2 + .../README.md | 241 ++++++++++++ .../README_EN.md | 352 ++++++++++++++++++ .../Solution.cpp | 19 + .../Solution.go | 17 + .../Solution.java | 18 + .../Solution.py | 13 + .../Solution.rs | 31 ++ .../Solution.ts | 22 ++ solution/README.md | 1 + solution/README_EN.md | 1 + 26 files changed, 747 insertions(+) create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/README.md create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/README_EN.md create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.cpp create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.go create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.java create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.py create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.rs create mode 100644 solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.ts diff --git a/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README.md b/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README.md index 12d29540153b6..4f6e568d439c2 100644 --- a/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README.md +++ b/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3633.Earliest%20Finish%20Time%20for%20Land%20and%20Water%20Rides%20I/README.md +rating: 1342 +source: 第 162 场双周赛 Q1 --- diff --git a/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README_EN.md b/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README_EN.md index 3aa6c3401305c..38cceb7d73a45 100644 --- a/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README_EN.md +++ b/solution/3600-3699/3633.Earliest Finish Time for Land and Water Rides I/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Easy edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3633.Earliest%20Finish%20Time%20for%20Land%20and%20Water%20Rides%20I/README_EN.md +rating: 1342 +source: Biweekly Contest 162 Q1 --- diff --git a/solution/3600-3699/3634.Minimum Removals to Balance Array/README.md b/solution/3600-3699/3634.Minimum Removals to Balance Array/README.md index 9477d7c3074f8..8e5089754690f 100644 --- a/solution/3600-3699/3634.Minimum Removals to Balance Array/README.md +++ b/solution/3600-3699/3634.Minimum Removals to Balance Array/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3634.Minimum%20Removals%20to%20Balance%20Array/README.md +rating: 1453 +source: 第 162 场双周赛 Q2 --- diff --git a/solution/3600-3699/3634.Minimum Removals to Balance Array/README_EN.md b/solution/3600-3699/3634.Minimum Removals to Balance Array/README_EN.md index dfa0844b84f67..16af384406b2b 100644 --- a/solution/3600-3699/3634.Minimum Removals to Balance Array/README_EN.md +++ b/solution/3600-3699/3634.Minimum Removals to Balance Array/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3634.Minimum%20Removals%20to%20Balance%20Array/README_EN.md +rating: 1453 +source: Biweekly Contest 162 Q2 --- diff --git a/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README.md b/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README.md index 6ed3932715dea..aff643c82965c 100644 --- a/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README.md +++ b/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3635.Earliest%20Finish%20Time%20for%20Land%20and%20Water%20Rides%20II/README.md +rating: 1869 +source: 第 162 场双周赛 Q3 --- diff --git a/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README_EN.md b/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README_EN.md index c7bc7cb5fae0d..8e8cd77c0e966 100644 --- a/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README_EN.md +++ b/solution/3600-3699/3635.Earliest Finish Time for Land and Water Rides II/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3635.Earliest%20Finish%20Time%20for%20Land%20and%20Water%20Rides%20II/README_EN.md +rating: 1869 +source: Biweekly Contest 162 Q3 --- diff --git a/solution/3600-3699/3636.Threshold Majority Queries/README.md b/solution/3600-3699/3636.Threshold Majority Queries/README.md index a91adf357b44f..997f601d14c22 100644 --- a/solution/3600-3699/3636.Threshold Majority Queries/README.md +++ b/solution/3600-3699/3636.Threshold Majority Queries/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 困难 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3636.Threshold%20Majority%20Queries/README.md +rating: 2451 +source: 第 162 场双周赛 Q4 --- diff --git a/solution/3600-3699/3636.Threshold Majority Queries/README_EN.md b/solution/3600-3699/3636.Threshold Majority Queries/README_EN.md index 11d83afd6d682..6cf14892a2661 100644 --- a/solution/3600-3699/3636.Threshold Majority Queries/README_EN.md +++ b/solution/3600-3699/3636.Threshold Majority Queries/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Hard edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3636.Threshold%20Majority%20Queries/README_EN.md +rating: 2451 +source: Biweekly Contest 162 Q4 --- diff --git a/solution/3600-3699/3637.Trionic Array I/README.md b/solution/3600-3699/3637.Trionic Array I/README.md index 835b26d047c99..ffed0be6a6dfd 100644 --- a/solution/3600-3699/3637.Trionic Array I/README.md +++ b/solution/3600-3699/3637.Trionic Array I/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3637.Trionic%20Array%20I/README.md +rating: 1263 +source: 第 461 场周赛 Q1 --- diff --git a/solution/3600-3699/3637.Trionic Array I/README_EN.md b/solution/3600-3699/3637.Trionic Array I/README_EN.md index 57f3219882e2c..36e016c8c1399 100644 --- a/solution/3600-3699/3637.Trionic Array I/README_EN.md +++ b/solution/3600-3699/3637.Trionic Array I/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Easy edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3637.Trionic%20Array%20I/README_EN.md +rating: 1263 +source: Weekly Contest 461 Q1 --- diff --git a/solution/3600-3699/3638.Maximum Balanced Shipments/README.md b/solution/3600-3699/3638.Maximum Balanced Shipments/README.md index 3c06b5821b1c5..6cbfca4007fcf 100644 --- a/solution/3600-3699/3638.Maximum Balanced Shipments/README.md +++ b/solution/3600-3699/3638.Maximum Balanced Shipments/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3638.Maximum%20Balanced%20Shipments/README.md +rating: 1463 +source: 第 461 场周赛 Q2 --- diff --git a/solution/3600-3699/3638.Maximum Balanced Shipments/README_EN.md b/solution/3600-3699/3638.Maximum Balanced Shipments/README_EN.md index a549ac9a93046..6337a15767728 100644 --- a/solution/3600-3699/3638.Maximum Balanced Shipments/README_EN.md +++ b/solution/3600-3699/3638.Maximum Balanced Shipments/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3638.Maximum%20Balanced%20Shipments/README_EN.md +rating: 1463 +source: Weekly Contest 461 Q2 --- diff --git a/solution/3600-3699/3639.Minimum Time to Activate String/README.md b/solution/3600-3699/3639.Minimum Time to Activate String/README.md index 4a7d30b676b67..a4a8f5125019d 100644 --- a/solution/3600-3699/3639.Minimum Time to Activate String/README.md +++ b/solution/3600-3699/3639.Minimum Time to Activate String/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 中等 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3639.Minimum%20Time%20to%20Activate%20String/README.md +rating: 1853 +source: 第 461 场周赛 Q3 --- diff --git a/solution/3600-3699/3639.Minimum Time to Activate String/README_EN.md b/solution/3600-3699/3639.Minimum Time to Activate String/README_EN.md index 9078f0b11529c..312bff28043a7 100644 --- a/solution/3600-3699/3639.Minimum Time to Activate String/README_EN.md +++ b/solution/3600-3699/3639.Minimum Time to Activate String/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Medium edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3639.Minimum%20Time%20to%20Activate%20String/README_EN.md +rating: 1853 +source: Weekly Contest 461 Q3 --- diff --git a/solution/3600-3699/3640.Trionic Array II/README.md b/solution/3600-3699/3640.Trionic Array II/README.md index f2c8f64203aca..018d167451ad4 100644 --- a/solution/3600-3699/3640.Trionic Array II/README.md +++ b/solution/3600-3699/3640.Trionic Array II/README.md @@ -2,6 +2,8 @@ comments: true difficulty: 困难 edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3640.Trionic%20Array%20II/README.md +rating: 2277 +source: 第 461 场周赛 Q4 --- diff --git a/solution/3600-3699/3640.Trionic Array II/README_EN.md b/solution/3600-3699/3640.Trionic Array II/README_EN.md index aba68cd5724d3..d781c7ddd4bac 100644 --- a/solution/3600-3699/3640.Trionic Array II/README_EN.md +++ b/solution/3600-3699/3640.Trionic Array II/README_EN.md @@ -2,6 +2,8 @@ comments: true difficulty: Hard edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3640.Trionic%20Array%20II/README_EN.md +rating: 2277 +source: Weekly Contest 461 Q4 --- diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/README.md b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/README.md new file mode 100644 index 0000000000000..a2af3ddce3528 --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/README.md @@ -0,0 +1,241 @@ +--- +comments: true +difficulty: 中等 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3641.Longest%20Semi-Repeating%20Subarray/README.md +--- + + + +# [3641. 最长半重复子数组 🔒](https://leetcode.cn/problems/longest-semi-repeating-subarray) + +[English Version](/solution/3600-3699/3641.Longest%20Semi-Repeating%20Subarray/README_EN.md) + +## 题目描述 + + + +

给定一个长度为  n 的整数数组 nums 和一个整数 k

+ +

半重复 子数组是指最多有 k 个元素重复(即出现超过一次)的连续子数组。

+ +

返回 nums 中最长 半重复 子数组的长度。

+ +

 

+ +

示例 1:

+ +
+

输入:nums = [1,2,3,1,2,3,4], k = 2

+ +

输出:6

+ +

解释:

+ +

最长的半重复子数组是 [2, 3, 1, 2, 3, 4],其中有 2 个重复元素(2 和 3)。

+
+ +

示例 2:

+ +
+

输入:nums = [1,1,1,1,1], k = 4

+ +

输出:5

+ +

解释:

+ +

最长的半重复子数组是 [1, 1, 1, 1, 1],其中只有 1 个重复元素(1)。

+
+ +

示例 3:

+ +
+

输入:nums = [1,1,1,1,1], k = 0

+ +

输出:1

+ +

解释:

+ +

最长的半重复子数组是 [1],其中没有重复元素。

+
+ +

 

+ +

提示:

+ + + + + +## 解法 + + + +### 方法一:滑动窗口 + +我们使用双指针 $l$ 和 $r$ 维护一个滑动窗口,右指针不断向右移动,并使用哈希表 $\textit{cnt}$ 记录每个元素在当前窗口内出现的次数。 + +当某个元素的出现次数从 $1$ 变为 $2$ 时,表示当前有一个新的重复元素,我们将重复元素的计数器 $\textit{cur}$ 加 $1$。当重复元素的计数器大于 $k$ 时,说明当前窗口不满足条件,我们需要移动左指针,直到重复元素的计数器不大于 $k$ 为止。在移动左指针的过程中,如果某个元素的出现次数从 $2$ 变为 $1$,表示当前少了一个重复元素,我们将重复元素的计数器减 $1$。然后,我们更新答案,即 $\textit{ans} = \max(\textit{ans}, r - l + 1)$。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。 + + + +#### Python3 + +```python +class Solution: + def longestSubarray(self, nums: List[int], k: int) -> int: + cnt = defaultdict(int) + ans = cur = l = 0 + for r, x in enumerate(nums): + cnt[x] += 1 + cur += cnt[x] == 2 + while cur > k: + cnt[nums[l]] -= 1 + cur -= cnt[nums[l]] == 1 + l += 1 + ans = max(ans, r - l + 1) + return ans +``` + +#### Java + +```java +class Solution { + public int longestSubarray(int[] nums, int k) { + Map cnt = new HashMap<>(); + int ans = 0, cur = 0, l = 0; + for (int r = 0; r < nums.length; ++r) { + if (cnt.merge(nums[r], 1, Integer::sum) == 2) { + ++cur; + } + while (cur > k) { + if (cnt.merge(nums[l++], -1, Integer::sum) == 1) { + --cur; + } + } + ans = Math.max(ans, r - l + 1); + } + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestSubarray(vector& nums, int k) { + unordered_map cnt; + int ans = 0, cur = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + if (++cnt[nums[r]] == 2) { + ++cur; + } + while (cur > k) { + if (--cnt[nums[l++]] == 1) { + --cur; + } + } + ans = max(ans, r - l + 1); + } + return ans; + } +}; +``` + +#### Go + +```go +func longestSubarray(nums []int, k int) (ans int) { + cnt := make(map[int]int) + cur, l := 0, 0 + for r := 0; r < len(nums); r++ { + if cnt[nums[r]]++; cnt[nums[r]] == 2 { + cur++ + } + for cur > k { + if cnt[nums[l]]--; cnt[nums[l]] == 1 { + cur-- + } + l++ + } + ans = max(ans, r-l+1) + } + return +} +``` + +#### TypeScript + +```ts +function longestSubarray(nums: number[], k: number): number { + const cnt: Map = new Map(); + let [ans, cur, l] = [0, 0, 0]; + for (let r = 0; r < nums.length; r++) { + cnt.set(nums[r], (cnt.get(nums[r]) || 0) + 1); + if (cnt.get(nums[r]) === 2) { + cur++; + } + + while (cur > k) { + cnt.set(nums[l], cnt.get(nums[l])! - 1); + if (cnt.get(nums[l]) === 1) { + cur--; + } + l++; + } + + ans = Math.max(ans, r - l + 1); + } + + return ans; +} +``` + +#### Rust + +```rust +use std::collections::HashMap; + +impl Solution { + pub fn longest_subarray(nums: Vec, k: i32) -> i32 { + let mut cnt = HashMap::new(); + let mut ans = 0; + let mut cur = 0; + let mut l = 0; + + for r in 0..nums.len() { + let entry = cnt.entry(nums[r]).or_insert(0); + *entry += 1; + if *entry == 2 { + cur += 1; + } + + while cur > k { + let entry = cnt.entry(nums[l]).or_insert(0); + *entry -= 1; + if *entry == 1 { + cur -= 1; + } + l += 1; + } + + ans = ans.max(r - l + 1); + } + + ans as i32 + } +} +``` + + + + + + diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/README_EN.md b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/README_EN.md new file mode 100644 index 0000000000000..4474584e57a3e --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/README_EN.md @@ -0,0 +1,352 @@ +--- +comments: true +difficulty: Medium +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3641.Longest%20Semi-Repeating%20Subarray/README_EN.md +--- + + + +# [3641. Longest Semi-Repeating Subarray 🔒](https://leetcode.com/problems/longest-semi-repeating-subarray) + +[中文文档](/solution/3600-3699/3641.Longest%20Semi-Repeating%20Subarray/README.md) + +## Description + + + +

You are given an integer array nums of length n and an integer k.

+ +

A semi‑repeating subarray is a contiguous subarray in which at most k elements repeat (i.e., appear more than once).

+ +

Return the length of the longest semi‑repeating subarray in nums.

+ +

 

+

Example 1:

+ +
+

Input: nums = [1,2,3,1,2,3,4], k = 2

+ +

Output: 6

+ +

Explanation:

+ +

The longest semi-repeating subarray is [2, 3, 1, 2, 3, 4], which has two repeating elements (2 and 3).

+
+ +

Example 2:

+ +
+

Input: nums = [1,1,1,1,1], k = 4

+ +

Output: 5

+ +

Explanation:

+ +

The longest semi-repeating subarray is [1, 1, 1, 1, 1], which has only one repeating element (1).

+
+ +

Example 3:

+ +
+

Input: nums = [1,1,1,1,1], k = 0

+ +

Output: 1

+ +

Explanation:

+ +

The longest semi-repeating subarray is [1], which has no repeating elements.

+
+ +

 

+

Constraints:

+ +
    +
  • 1 <= nums.length <= 105
  • +
  • 1 <= nums[i] <= 105
  • +
  • 0 <= k <= nums.length
  • +
+ +

 

+ + +
+
+

FOR TESTING ONLY. WILL BE DELETED LATER.

+// Model solution has runtime of O(n log n), O(n*n) and above should TLE. + +
+# Bromelia
+
+import sys
+import random, json, string
+import math
+import datetime
+from collections import defaultdict
+ri = random.randint
+
+MAX_N   = 100_000
+MAX_VAL = 100_000
+
+def randomString(n, allowed):
+    return ''.join(random.choices(allowed, k=n))
+
+def randomUnique(x, y, n):
+    return random.sample(range(x, y + 1), n)
+
+def randomArray(x, y, n):
+    return [ri(x, y) for _ in range(n)]
+
+def shuffle(arr):
+    random.shuffle(arr)
+    return arr
+
+def pr(a):
+    file.write(str(a).replace(" ", "").replace("\'", "\"").replace("\"null\"", "null") + '\n')
+
+def prstr(a):
+    pr("\"" + a + "\"")
+
+
+def prtc(tc):
+    nums, k = tc
+    pr(nums)
+    pr(k)
+    
+def examples():
+    yield ([1, 2, 3, 1, 2, 3, 4], 2)
+    yield ([1, 1, 1, 1, 1], 4)
+    yield ([1, 1, 1, 1, 1], 0)
+
+def smallCases():
+    yield ([MAX_VAL], 0)
+    yield ([MAX_VAL], 1)
+
+    for len in range(1, 3 + 1):
+        nums = [0] * len
+
+        def recursiveGenerate(idx: int):
+            if idx == len:
+                for k in range(0, len + 1):
+                    yield (nums, k)
+            else:
+                for nextElement in range(1, len + 1):
+                    nums[idx] = nextElement
+                    yield from recursiveGenerate(idx + 1)
+
+        yield from recursiveGenerate(0)
+
+def randomCases():
+    params = [
+        (    4,    20,      10, 400),
+        (   21,  2000,    1000, 100),
+        (MAX_N, MAX_N,      10,   2),
+        (MAX_N, MAX_N,     500,   2),
+        (MAX_N, MAX_N, MAX_VAL,   2),
+    ]
+    for minLen, maxLen, maxVal, testCount in params:
+        for _ in range(testCount):
+            len = ri(minLen, maxLen)
+            k = ri(1, len)
+
+            nums = [0] * len
+            for i in range(len):
+                nums[i] = ri(1, maxVal)        
+
+            yield (nums, k)
+
+def cornerCases():
+    yield ([MAX_VAL] * MAX_N, 0)
+    yield ([MAX_VAL] * MAX_N, MAX_N)
+    yield ([i for i in range(1, MAX_N + 1)], 0)
+    yield ([i for i in range(1, MAX_N + 1)], MAX_N)
+    yield ([i // 2 + 1 for i in range(MAX_N)], MAX_N // 2 - 1)
+    yield ([i % (MAX_N // 2) + 1 for i in range(MAX_N)], MAX_N // 2 - 1)
+
+
+with open('test.txt', 'w') as file:
+    random.seed(0)
+    for tc in examples(): prtc(tc)
+    for tc in smallCases(): prtc(tc)
+    for tc in sorted(list(randomCases()), key = lambda x: len(x[0])): prtc(tc)
+    for tc in cornerCases(): prtc(tc)
+
+
+
+ + + +## Solutions + + + +### Solution 1: Sliding Window + +We use two pointers $l$ and $r$ to maintain a sliding window, where the right pointer continuously moves to the right, and we use a hash table $\textit{cnt}$ to record the number of occurrences of each element within the current window. + +When the occurrence count of an element changes from $1$ to $2$, it indicates that there is a new repeating element, so we increment the repeating element counter $\textit{cur}$ by $1$. When the repeating element counter exceeds $k$, it means the current window does not satisfy the condition, and we need to move the left pointer until the repeating element counter is no greater than $k$. During the process of moving the left pointer, if the occurrence count of an element changes from $2$ to $1$, it indicates that there is one less repeating element, so we decrement the repeating element counter by $1$. Then, we update the answer, i.e., $\textit{ans} = \max(\textit{ans}, r - l + 1)$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. + + + +#### Python3 + +```python +class Solution: + def longestSubarray(self, nums: List[int], k: int) -> int: + cnt = defaultdict(int) + ans = cur = l = 0 + for r, x in enumerate(nums): + cnt[x] += 1 + cur += cnt[x] == 2 + while cur > k: + cnt[nums[l]] -= 1 + cur -= cnt[nums[l]] == 1 + l += 1 + ans = max(ans, r - l + 1) + return ans +``` + +#### Java + +```java +class Solution { + public int longestSubarray(int[] nums, int k) { + Map cnt = new HashMap<>(); + int ans = 0, cur = 0, l = 0; + for (int r = 0; r < nums.length; ++r) { + if (cnt.merge(nums[r], 1, Integer::sum) == 2) { + ++cur; + } + while (cur > k) { + if (cnt.merge(nums[l++], -1, Integer::sum) == 1) { + --cur; + } + } + ans = Math.max(ans, r - l + 1); + } + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + int longestSubarray(vector& nums, int k) { + unordered_map cnt; + int ans = 0, cur = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + if (++cnt[nums[r]] == 2) { + ++cur; + } + while (cur > k) { + if (--cnt[nums[l++]] == 1) { + --cur; + } + } + ans = max(ans, r - l + 1); + } + return ans; + } +}; +``` + +#### Go + +```go +func longestSubarray(nums []int, k int) (ans int) { + cnt := make(map[int]int) + cur, l := 0, 0 + for r := 0; r < len(nums); r++ { + if cnt[nums[r]]++; cnt[nums[r]] == 2 { + cur++ + } + for cur > k { + if cnt[nums[l]]--; cnt[nums[l]] == 1 { + cur-- + } + l++ + } + ans = max(ans, r-l+1) + } + return +} +``` + +#### TypeScript + +```ts +function longestSubarray(nums: number[], k: number): number { + const cnt: Map = new Map(); + let [ans, cur, l] = [0, 0, 0]; + for (let r = 0; r < nums.length; r++) { + cnt.set(nums[r], (cnt.get(nums[r]) || 0) + 1); + if (cnt.get(nums[r]) === 2) { + cur++; + } + + while (cur > k) { + cnt.set(nums[l], cnt.get(nums[l])! - 1); + if (cnt.get(nums[l]) === 1) { + cur--; + } + l++; + } + + ans = Math.max(ans, r - l + 1); + } + + return ans; +} +``` + +#### Rust + +```rust +use std::collections::HashMap; + +impl Solution { + pub fn longest_subarray(nums: Vec, k: i32) -> i32 { + let mut cnt = HashMap::new(); + let mut ans = 0; + let mut cur = 0; + let mut l = 0; + + for r in 0..nums.len() { + let entry = cnt.entry(nums[r]).or_insert(0); + *entry += 1; + if *entry == 2 { + cur += 1; + } + + while cur > k { + let entry = cnt.entry(nums[l]).or_insert(0); + *entry -= 1; + if *entry == 1 { + cur -= 1; + } + l += 1; + } + + ans = ans.max(r - l + 1); + } + + ans as i32 + } +} +``` + + + + + + diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.cpp b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.cpp new file mode 100644 index 0000000000000..9f5ac4f8252ed --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + int longestSubarray(vector& nums, int k) { + unordered_map cnt; + int ans = 0, cur = 0, l = 0; + for (int r = 0; r < nums.size(); ++r) { + if (++cnt[nums[r]] == 2) { + ++cur; + } + while (cur > k) { + if (--cnt[nums[l++]] == 1) { + --cur; + } + } + ans = max(ans, r - l + 1); + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.go b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.go new file mode 100644 index 0000000000000..550d46c0b4e60 --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.go @@ -0,0 +1,17 @@ +func longestSubarray(nums []int, k int) (ans int) { + cnt := make(map[int]int) + cur, l := 0, 0 + for r := 0; r < len(nums); r++ { + if cnt[nums[r]]++; cnt[nums[r]] == 2 { + cur++ + } + for cur > k { + if cnt[nums[l]]--; cnt[nums[l]] == 1 { + cur-- + } + l++ + } + ans = max(ans, r-l+1) + } + return +} diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.java b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.java new file mode 100644 index 0000000000000..3580eac3b7c61 --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.java @@ -0,0 +1,18 @@ +class Solution { + public int longestSubarray(int[] nums, int k) { + Map cnt = new HashMap<>(); + int ans = 0, cur = 0, l = 0; + for (int r = 0; r < nums.length; ++r) { + if (cnt.merge(nums[r], 1, Integer::sum) == 2) { + ++cur; + } + while (cur > k) { + if (cnt.merge(nums[l++], -1, Integer::sum) == 1) { + --cur; + } + } + ans = Math.max(ans, r - l + 1); + } + return ans; + } +} \ No newline at end of file diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.py b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.py new file mode 100644 index 0000000000000..b9d6f46678255 --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.py @@ -0,0 +1,13 @@ +class Solution: + def longestSubarray(self, nums: List[int], k: int) -> int: + cnt = defaultdict(int) + ans = cur = l = 0 + for r, x in enumerate(nums): + cnt[x] += 1 + cur += cnt[x] == 2 + while cur > k: + cnt[nums[l]] -= 1 + cur -= cnt[nums[l]] == 1 + l += 1 + ans = max(ans, r - l + 1) + return ans diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.rs b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.rs new file mode 100644 index 0000000000000..0a36a1d672db7 --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.rs @@ -0,0 +1,31 @@ +use std::collections::HashMap; + +impl Solution { + pub fn longest_subarray(nums: Vec, k: i32) -> i32 { + let mut cnt = HashMap::new(); + let mut ans = 0; + let mut cur = 0; + let mut l = 0; + + for r in 0..nums.len() { + let entry = cnt.entry(nums[r]).or_insert(0); + *entry += 1; + if *entry == 2 { + cur += 1; + } + + while cur > k { + let entry = cnt.entry(nums[l]).or_insert(0); + *entry -= 1; + if *entry == 1 { + cur -= 1; + } + l += 1; + } + + ans = ans.max(r - l + 1); + } + + ans as i32 + } +} diff --git a/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.ts b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.ts new file mode 100644 index 0000000000000..18846dc130b69 --- /dev/null +++ b/solution/3600-3699/3641.Longest Semi-Repeating Subarray/Solution.ts @@ -0,0 +1,22 @@ +function longestSubarray(nums: number[], k: number): number { + const cnt: Map = new Map(); + let [ans, cur, l] = [0, 0, 0]; + for (let r = 0; r < nums.length; r++) { + cnt.set(nums[r], (cnt.get(nums[r]) || 0) + 1); + if (cnt.get(nums[r]) === 2) { + cur++; + } + + while (cur > k) { + cnt.set(nums[l], cnt.get(nums[l])! - 1); + if (cnt.get(nums[l]) === 1) { + cur--; + } + l++; + } + + ans = Math.max(ans, r - l + 1); + } + + return ans; +} diff --git a/solution/README.md b/solution/README.md index 6c5fa077673b0..9d4cb5ecf1224 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3651,6 +3651,7 @@ | 3638 | [平衡装运的最大数量](/solution/3600-3699/3638.Maximum%20Balanced%20Shipments/README.md) | | 中等 | 第 461 场周赛 | | 3639 | [变为活跃状态的最小时间](/solution/3600-3699/3639.Minimum%20Time%20to%20Activate%20String/README.md) | | 中等 | 第 461 场周赛 | | 3640 | [三段式数组 II](/solution/3600-3699/3640.Trionic%20Array%20II/README.md) | | 困难 | 第 461 场周赛 | +| 3641 | [最长半重复子数组](/solution/3600-3699/3641.Longest%20Semi-Repeating%20Subarray/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index 1da4c5c75bfd9..d1c82c57acee8 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3649,6 +3649,7 @@ Press Control + F(or Command + F on | 3638 | [Maximum Balanced Shipments](/solution/3600-3699/3638.Maximum%20Balanced%20Shipments/README_EN.md) | | Medium | Weekly Contest 461 | | 3639 | [Minimum Time to Activate String](/solution/3600-3699/3639.Minimum%20Time%20to%20Activate%20String/README_EN.md) | | Medium | Weekly Contest 461 | | 3640 | [Trionic Array II](/solution/3600-3699/3640.Trionic%20Array%20II/README_EN.md) | | Hard | Weekly Contest 461 | +| 3641 | [Longest Semi-Repeating Subarray](/solution/3600-3699/3641.Longest%20Semi-Repeating%20Subarray/README_EN.md) | | Medium | 🔒 | ## Copyright