题目描述
给定一个未排序的整数数组 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
题解思路
方法一:排序(非进阶)
- 在遍历数组时候对于数值相同的元素需要保存 len ,不能重制为1
- 遍历完成后,取 max_len 和 len 的最大值
复杂度分析:
- 时间复杂度 O( n l o g ( n ) nlog(n) nlog(n))
- 空间复杂度 O( n n n)
代码实现:
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if(nums.size() < 2) return nums.size();
sort(nums.begin(), nums.end());
int max_len = 0, len = 1;
for(int i = 1; i < nums.size(); ++i){
if(nums[i] == nums[i-1] + 1){
++len;
}
else if(nums[i] == nums[i-1]){
// 什么也不用做
}
else{
if(max_len < len) max_len = len;
len = 1;
}
if(i == nums.size()-1){
if(max_len < len) max_len = len;
}
}
return max_len;
}
};
方法二:哈希表(进阶)
- 由于序列里的元素是无序的,又要求 O(n),首先要想到用哈希表。
- 用一个哈希表 unordered_map<int, bool> used 记录每个元素是否使用,对每个元素,以该元素为中心,往左右扩张,直到不连续为止,记录下最长的长度。
复杂度分析:
- 时间复杂度 O(n)
- 空间复杂度 O(n)
代码实现:
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_map<int, bool> m;
for(auto i : nums) m[i] = false;
int Max = 0;
for(auto i : nums){
if(m[i]) continue;
int len = 1;
for(int j = i+1; m.find(j) != m.end(); ++j){
m[j] = true;
++len;
}
for(int j = i-1; m.find(j) != m.end(); --j){
m[j] = true;
++len;
}
Max = max(len, Max);
}
return Max;
}
};
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
// 将字符串转成数字存入数组,间隔符为 ','
while (cin >> s) {
vector<int> nums;
unordered_map<int, bool> m;
int num;
while (s.size()) {
int n = s.find(',');
if (n == -1) {
break;
}
string str = s.substr(0, n);
num = stoi(str);
nums.push_back(num);
s = s.substr(n + 1, s.size() - 1 - n);
}
num = stoi(s);
nums.push_back(num);
for (auto i : nums) m[i] = false;
int Max = 0;
for (auto i : nums) {
if (m[i]) continue;
int len = 1;
for (int j = i + 1; m.find(j) != m.end(); ++j) {
m[j] = true;
++len;
}
for (int j = i - 1; m.find(j) != m.end(); --j) {
m[j] = true;
++len;
}
Max = max(len, Max);
}
cout << Max << endl;
}
}