题目信息
LeetCode地址: . - 力扣(LeetCode)
题目理解
题目要求O(n)的时间复杂度,也就不能使用排序或者暴力枚举的方法解题。
暴力枚举的缺陷在于重复计算。
我们通过以下数列来说明存在哪些重复计算:
4,3,2,1。
第一个数是4, 4+1=5, 5不存在,累加结束;最大连续长度是1
第二个数是3,3+1=4,4存在;4+1=5, 5不存在,累加结束;最大连续长度是2
第三个数是2, 2+1=3,3+1=4,4+1=5, 5不存在,累加结束;最大连续长度是3
第四个数是1,1+1=2,2+1=3,3+1=4,4+1=5, 5不存在,累加结束;最大连续长度是4
可以看到,每一个更小的数载计算连续长度时,都重复进行了比他大一个数的计算过程。
为了尽可能的延后这个计算,我们可以:如果当前数的减1的数存在,则先跳过这个数,否则进行累加计算。
第一个数是4, 4-1=3, 3存在,跳过这个数。
第二个数是3,3-1=2,2存在;跳过这个数。
第三个数是2, 2-1=1, 1存在;跳过这个数。
第四个数是1,1-1=0 0不存在,开始计算累加长度:1+1=2,2+1=3,3+1=4,4+1=5, 5不存在,累加结束;最大连续长度是4
可以看到,这样调整后的计算过程没有任何一步重复。
同时,我们也可以通过反证法轻而易举的证明该方法一定能够得到最大长度。
先假设我们得到的结果是largest, 而存在一种更长的数列betterArray={m1, m2, m3... mn}能够做到mn-m1+1= bigger, 而bigger > largest.
而通过我们的方法,一定能够捕捉并跳过m2,m3...到mn, 而从m1开始计算长度,故 一定能满足
largest >= (mn-m1+1). 所以假设一定不成立,故证明我们的方法一定能得到最优解。
写法1
public int longestConsecutive(int[] nums) {
int max = 0;
Set<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
for (int num: nums) {
if (!set.contains(num-1)) {
int current = 1;
while (set.contains(++num)) {
current++;
}
max = Math.max(max, current);
}
}
return max;
}
本文介绍了如何利用哈希集和优化策略在LeetCode题目中找到一个整数数组中的最大连续递增子序列,避免了暴力枚举中的重复计算,以O(n)的时间复杂度求解。作者通过举例和反证法证明了这种方法的有效性。
603

被折叠的 条评论
为什么被折叠?



