3641. Longest Semi-Repeating Subarray 🔒
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}\).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|