哈希:最长连续序列
题目描述:无序的整型数组,求连续最长序列。
输入:nums = [100,4,200,1,3,2]
输出:4 (因为:最长数字连续序列是 [1, 2, 3, 4],长度为 4。)
说明:连续指的是数字的连续,算法要求时间复杂度为O(n)。
求解思路:遍历数组,依次往下找。在找的过程中,因为求最长,所以找的时候需要确定当前数是序列最小,否则没必要。用Set容器存储所有数作为辅助,方便确定我们找的连续序列中的数是否存在。(因为求解的最长序列,不要求在数组连续,所以想到用set去重也不会影响结果。)
class Solution {public int longestConsecutive(int[] nums) {int longest = 0;// 把所有数存在set中,方便查找HashSet<Integer> set = new HashSet<>();for (int num : nums) {set.add(num);}// 遍历,寻找最长连续序列for (int i = 0; i < nums.length; i++) {int curNum = nums[i];//判断前驱存不存在很重要!确保序列是从最小的curNum开始if (!set.contains(curNum - 1)) {// curNum是序列的开头,len为1int len = 1;// 寻找curNum的下个数。前置++,++curNum和curNum+1效果一样,但是++或者--一般用在遍历,curNum+1更方便理解while (set.contains(curNum + 1)) {len += 1;curNum += 1;}longest = Math.max(longest, len);}}return longest;}
}
以上代码,会报超时。
再次优化,遍历set代替遍历nums。
class Solution {public int longestConsecutive(int[] nums) {int longest = 0;// 把所有数存在set中,方便查找HashSet<Integer> set = new HashSet<>();for (int num : nums) {set.add(num);}// 遍历set,因为set中比原数组数少,不存在重复的for (Integer num : set) {// 之所以这里需要使用curNum把num记录下来,因为num是for循环进行的条件。和for(i...len)不同int curNum = num;if (!set.contains(curNum - 1)) {int len = 1;while (set.contains(curNum + 1)) {len += 1;curNum += 1;}longest = Math.max(longest, len);}}return longest;}
}
总结:判断cur-1是核心,确保序列开头最小。遍历set是其二,省去重复的计算。
联系地址:128. 最长连续序列 - 力扣(LeetCode)