外观
🚀 最长不重复的子数组
⭐ 题目日期:
百度 - 2025/1/15,字节 - 2024/10/16
🌳 题目示例:
示例 1:
输入:[1, 2, 6, 3, 2, 4, 7]
输出:[6, 3, 2, 4, 7]
🧗难度系数:
⭐️ ⭐️ ⭐️
📝思路分析:
以上的算法就是面试中高频考点滑动窗口(Sliding Window),主要用于解决数组或字符串等连续数据结构上的子数组或子串问题,尤其是需要在 O(n) 的时间复杂度内解决的问题。
💻代码:
Java
public int[] longestSubarray(int[] nums) {
if (nums == null || nums.length == 0) {
return nums;
}
int start = 0;
int end = 0;
int curStart = 0;
Set<Integer> set = new HashSet<>();
set.add(nums[0]);
for (int i = 1; i < nums.length; i++) {
while (set.contains(nums[i])) {
set.remove(nums[curStart]);
curStart++;
}
set.add(nums[i]);
if (i - curStart > end - start) {
start = curStart;
end = i;
}
}
return Arrays.copyOfRange(nums, start, end + 1);
}
Python
def longest_subarray(nums):
if not nums:
return nums
start, end = 0, 0
cur_start = 0
num_set = set()
num_set.add(nums[0])
for i in range(1, len(nums)):
while nums[i] in num_set:
num_set.remove(nums[cur_start])
cur_start += 1
num_set.add(nums[i])
if i - cur_start > end - start:
start, end = cur_start, i
return nums[start:end + 1]
C++
#include <iostream>
#include <vector>
#include <unordered_set>
#include <algorithm>
using namespace std;
vector<int> longestSubarray(const vector<int>& nums) {
if (nums.empty()) {
return nums;
}
int start = 0, end = 0, curStart = 0;
unordered_set<int> numSet;
numSet.insert(nums[0]);
for (int i = 1; i < nums.size(); i++) {
while (numSet.find(nums[i]) != numSet.end()) {
numSet.erase(nums[curStart]);
curStart++;
}
numSet.insert(nums[i]);
if (i - curStart > end - start) {
start = curStart;
end = i;
}
}
return vector<int>(nums.begin() + start, nums.begin() + end + 1);
}
🚵🏻复杂度分析:
时间复杂度:O(n), 遍历一遍子数组,有重复的元素,将其从 set 里面删除,数组中的每个元素最多被访问两遍
空间复杂度:O(n), 用于 set 存储当前子数组的元素