LeetCode 128.最长连续序列
128. 最长连续序列
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
这个题就是让你在给定的数组中找一个连续递增的序列,求 这个递增序列的最大长度。时间复杂度要求是O(n),直接枪毙了使用排序的算法。
偷瞄一眼tag,并查集,可是这个我已经忘了啊- -马上就去恶补了一下并查集。
其实并查集就是将有关系的一组数据分到同一个组里面,在我们这个题里什么叫做有关系呢?这个关系就在于连续这个字眼了。
public int longestConsecutive(int[] nums) { HashMap<Integer, Integer> map = new HashMap<>(); int max = 0; for(int num: nums){ if(map.containsKey(num)){ continue; } int left = num-1; int right = num+1; //这里其实就是把并查集中二维数组的第二维的分组号变成了它连续序列的长度。 int leftCount = map.getOrDefault(left,0); //右手边 int rightCount = map.getOrDefault(right,0); int currentCount = leftCount + rightCount + 1; max = Math.max(currentCount,max); //我们需要将这个范围内的数字归纳到同一个分组中,分组用分组的长度来表示。 //正常的话我们需要将这个count的范围内的数据全部都改成相同的分组,但是我们这里只维护了最远的边界的值。为什么呢? //假如说我们现在有 123 567这两个分组,我们插入4,插入之后我们1号和7号的长度就会被修改成7。那么下次我们能得到的最大长度会在什么地方出现呢? //只有插入0或者8这两个数字,因为我们已经排除了出现重复数字的情况了。所以我们插入0的时候,我们读取的是1号的长度,修改的是7号的长度 //这时候插入仍然还是在-1和8号位可以达到最大的长度。 map.put(num,currentCount); map.put(num - leftCount,currentCount); map.put(num + rightCount, currentCount); } return max; }
这个算法是参考热评第一名的,我认为它的思想很好。秒掉了我所想的并查集思想。。我的并查集思想最少都要O(nk)的时间复杂度,因为要把并查集中同一个分组的元素的组号都要改一次。
这个只需要维护边界值的最大长度即可,我自己想了一下它的思想,写到了这个注释上。