思路1:hash ——>时间复杂度O(n)
技巧: hash 可以用unordered_map
分析题目:不需要键->值,只要保存存在的那些值就可以了,所以可以考虑set来节省存储空间
题目需要去重+hash+不需要映射 ——>unorderes_set
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int n = nums.size();
unordered_set<int> st(nums.begin(), nums.end());
int ans = 0;
for (auto& a : st) {
if (!st.count(a - 1)) {
int tmp = a, cnt = 0;
while (st.count(tmp)) {
cnt++;
tmp++;
}
ans = max(ans, cnt);
}
}
return ans;
}
};
思路2:并查集 ——>查找合并近似O(1),因此总时间复杂度O(n)
并查集只能定义数组的样子,不能处理负数?放弃了。。。
技巧: father数组 可以用unordered_map啊
father数组中存的是较大的值,因此 union(较小值, 较大值)
class Solution {
public:
unordered_map<int, int> father;
int findfather(int u) {
if (u == father[u]) return u;
return father[u] = findfather(father[u]);
}
void unite(int u, int v) {
int fau = findfather(u);
int fav = findfather(v);
if (fau != fav) father[fau] = fav;
}
int longestConsecutive(vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n; ++i) {
father[nums[i]] = nums[i];
}
for (auto &m : father) {
if (father.count(m.first + 1)) {
unite(m.first, m.first + 1);
}
}
int ans = 0;
for (auto &m : father) {
ans = max(ans, findfather(m.first) - m.first + 1);
}
return ans;
}
};
思路三:排序 时间O(nlogn)
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int n = nums.size();
if (!n) return 0;
sort(nums.begin(), nums.end());
int cnt = 1, ans = 1;
for (int i = 1; i < n; ++i) {
if (nums[i] == nums[i - 1]) continue; //
else if (nums[i] == nums[i - 1] + 1) {
cnt++;
}
else cnt = 1;
ans = max(ans, cnt);
}
return ans;
}
};
易错点:当 nums[i] == nums[i - 1]时直接continue