题目描述:
给定一个长度为 n 的整数序列 a1,a2,…,an,请你找出最长的不包含重复元素的连续子数组,并输出它的长度。
例如,序列中的子数组 a[l],a[l+1],…,a[r] 满足以下条件:对于任意 i,j(i=j),都有 ai=aj。
请编写程序来求解这个问题。
输出一个整数,表示最长不包含重复元素的连续子数组的长度。
7
1 2 3 1 2 3 4
4
5
1 1 1 1 1
1
给定一个长度为 n 的整数序列 a1,a2,…,an,请你找出最长的不包含重复元素的连续子数组,并输出它的长度。
我们可以使用滑动窗口(双指针)来高效解决这个问题。具体步骤如下:
初始化:
left
和 right
,都初始化为序列的起始位置0。seen
来记录当前窗口内出现的元素。maxLength
来记录当前找到的最长子数组长度,初始值为0。滑动窗口遍历:
right
指针从左到右移动。a[right]
:
a[right]
已经存在于 seen
集合中,说明当前窗口内有重复元素,需要通过移动 left
指针来缩小窗口,直到移除重复的元素。while a[right] in seen:
seen.remove(a[left])
left += 1
a[right]
添加到 seen
集合中。right - left + 1
,如果大于 maxLength
,则更新 maxLength
。seen.add(a[right])
maxLength = max(maxLength, right - left + 1)
最终结果:
maxLength
即为所求的最长不包含重复元素的连续子数组的长度。def longest_unique_subarray_length(a):
seen = set() # 用于记录当前窗口中的元素
left = 0 # 左指针
max_length = 0 # 最长不重复子数组的长度
# 遍历数组
for right in range(len(a)):
# 如果当前元素在窗口中已经存在,收缩窗口
while a[right] in seen:
seen.remove(a[left])
left += 1
# 加入当前元素
seen.add(a[right])
# 更新最大长度
max_length = max(max_length, right - left + 1)
return max_length
# 主函数,读取输入
if __name__ == '__main__':
n = int(input()) # 读取序列长度
a = list(map(int, input().split())) # 读取整数序列
print(longest_unique_subarray_length(a))
以样例输入 1为例:
7
1 2 3 1 2 3 4
left = 0
,right = 0
,seen = {}
,max_length = 0
。right
指针:
right = 0
,元素为1,加入 seen
,seen = {1}
,max_length = 1
。right = 1
,元素为2,加入 seen
,seen = {1, 2}
,max_length = 2
。right = 2
,元素为3,加入 seen
,seen = {1, 2, 3}
,max_length = 3
。right = 3
,元素为1,已存在于 seen
,移动 left
到1,移除元素1,加入新的1,seen = {2, 3, 1}
,max_length
保持为3。right = 4
,元素为2,已存在于 seen
,移动 left
到2,移除元素2,加入新的2,seen = {3, 1, 2}
,max_length
保持为3。right = 5
,元素为3,已存在于 seen
,移动 left
到3,移除元素3,加入新的3,seen = {1, 2, 3}
,max_length
保持为3。right = 6
,元素为4,加入 seen
,seen = {1, 2, 3, 4}
,max_length
更新为4。最终,最长不包含重复元素的连续子数组为 [1, 2, 3, 4]
,其长度为4。