给定一个未排序的整数数组 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
自己的思路
判断逻辑:跳过相同元素,后一个元素=前一个元素+1
1、如果数组长度为0,即数组为空,则直接返回0
2、否则,定义变量count(计算连续的序列长度)和max(存储最长序列的长度)
3、将数组从小到大排序
4、使用for循环遍历数组,如果符合判断逻辑,count就加1
5、如果count大于max,则max重新赋值为count
代码实现
class Solution {
public int longestConsecutive(int[] nums) {
if (nums .length == 0) {
return 0;
}
Arrays.sort(nums);
int count = 1;
int max = 1;
for(var i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i + 1]){
continue;
}
if (nums[i] + 1 == nums[i + 1]) {
count++;
} else if (nums[i] != nums[i + 1]){
count = 1;
}
if (max < count) {
max = count;
}
}
return max;
}
}
时间复杂度
只遍历一次数组,空间复杂度为O(n)
力扣官方题解
1、利用集合的性质去重(免去了跳过相同元素的步骤)
2、定义变量longestStreak(存储最长序列的长度)
3、遍历集合获取当前元素currentNum:
(1)如果集合中没有"currentNum-1"的元素(比当前元素小1的元素),则当前序列的长度currentStreak为1,跳过后续的判断(例如集合[100, 4, 200, 1, 3, 2],判断元素100,集合中没有99,就不用再继续判断了。就算有元素101,也认为元素100的循环中最长序列长度为1。因为当遍历到101时,会计算上100,当前序列的长度currentStreak为2)
(2)如果循环查找集合中是否有"currentNum+1"的元素(比当前元素大1的元素),有的话:当前元素currentNum+1变为下一个元素(这样下次循环就会判断下一个是否存在连续的元素),当前序列的长度currentStreak+1
代码实现(直接复制了)
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> num_set = new HashSet<Integer>();
for (int num : nums) {
num_set.add(num);
}
int longestStreak = 0;
for (int num : num_set) {
if (!num_set.contains(num - 1)) {
int currentNum = num;
int currentStreak = 1;
while (num_set.contains(currentNum + 1)) {
currentNum += 1;
currentStreak += 1;
}
longestStreak = Math.max(longestStreak, currentStreak);
}
}
return longestStreak;
}
}
作者:力扣官方题解 链接:https://leetcode.cn/problems/longest-consecutive-sequence/solutions/276931/zui-chang-lian-xu-xu-lie-by-leetcode-solution/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
用哈希表反而效率更差了。。。