📅  最后修改于: 2023-12-03 15:26:45.026000             🧑  作者: Mango
给定一个长度为N的数组,检查任何长度为M的子数组是否连续重复至少K次,如果是,返回True,否则返回False。
暴力法
滑动窗口法
def check_repeat_subarray(nums, M, K):
if M <= 0 or K <= 0 or M * K > len(nums):
return False
# 计算每个长度为M的子数组出现的次数
subarray_count = {}
for i in range(len(nums) - M + 1):
subarray = tuple(nums[i:i+M])
subarray_count[subarray] = subarray_count.get(subarray, 0) + 1
# 滑动窗口,依次统计每个长度为M的子数组出现的次数
window_count = {}
for i in range(M):
window_count[tuple(nums[i:i+M])] = window_count.get(tuple(nums[i:i+M]), 0) + 1
left = 0
for right in range(M, len(nums) + 1):
# 如果该窗口子数组出现次数达到K,返回True
if window_count[tuple(nums[left:left+M])] == K:
return True
# 更新左窗口位置
window_count[tuple(nums[left:left+M])] -= 1
if window_count[tuple(nums[left:left+M])] == 0:
del window_count[tuple(nums[left:left+M])]
left += 1
# 更新右窗口位置
if right < len(nums):
window_count[tuple(nums[right:right+M])] = window_count.get(tuple(nums[right:right+M]), 0) + 1
# 子数组未连续重复至少K次
return False
相比暴力法,滑动窗口法大大降低了时间复杂度,空间复杂度增加了N的常数,但是总体开销不大。实际测试中,滑动窗口法的效率显著高于暴力法。