3. 最长连续序列
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
输入:nums = [0,3,7,2,5,8,4,6,0,1] 输出:9
我觉得这个时间复杂度不止O(N)❌
虽然看起来是O(N*N),但仔细看while循环,并不是按照nums[]再遍历一遍,而是通过nums[i]+1 来遍历哈希。
思路:从当前位置i开始找比nums[i]大的数据(在哈希表中找)
!!! 唯一不理解的点在于if语句,为什么是nums[i]-1判断,不是直接if(!numSet.contains(num)) !!!
- 这个判断逻辑本身就不成立 —— 因为 num 是从 numSet 里遍历出来的元素,numSet.contains(num) 永远是 true,
- 所以 !numSet.contains(num) 永远是 false,整个 if 块里的逻辑永远不会执行,最终结果只能是 0,完全错误。
原算法用 !numSet.contains(num-1) 找起点(当前数是连续序列的第一个数),然后往后找 num+1、num+2...;
反过来用 !numSet.contains(num+1) 找终点(当前数是连续序列的最后一个数),然后往前找 num-1、num-2...,最终能得到完全一样的结果。
1 class Solution { 2 public int longestConsecutive(int[] nums) { 3 if(nums==null || nums.length==0)return 0; 4 Set<Integer> numSet = new HashSet<>(); 5 for(int num : nums){ 6 numSet.add(num); 7 } 8 int len = 0; 9 10 for(int num : numSet){ 11 if(!numSet.contains(num-1)){ //只从 “连续序列的起点”(即当前数 -1 不存在于集合中)开始遍历,避免重复计算; 12 int cur_num = num; 13 int cur_len = 1; 14 15 while(numSet.contains(cur_num+1)){ 16 cur_num++; 17 cur_len++; 18 } 19 len = Math.max(len,cur_len); 20 } 21 } 22 return len; 23 } 24 }

浙公网安备 33010602011771号