LeetCode 面试经典 150_哈希表_最长连续序列(47_128_C++_中等)
LeetCode 面试经典 150_哈希表_最长连续序列(47_128_C++_中等)
- 题目描述:
- 输入输出样例:
- 题解:
- 解题思路:
- 思路一(暴力破解法(仅思路)):
- 思路二(哈希集合):
- 代码实现
- 代码实现(思路二(哈希集合)):
- 以思路二为例进行调试
题目描述:
给定一个未排序的整数数组 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
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
题解:
解题思路:
思路一(暴力破解法(仅思路)):
1、先进行排序后,再进行查找最长连续序列(注意重复元素的处理)。
2、复杂度分析:
① 时间复杂度:O(nlogn)。sort排序为O(nlogn),遍历查找最长连续序列为O(n)。
② 空间复杂度::O(1)。
思路二(哈希集合):
1、解决此问题首先要判断此元素是否是开始元素,假设当前元素是n 判断n-1是否存在,判断n-1是否存在可以自然的想到哈希集合。若当前元素是开始元素,则判断n+1,n+2… 累计连续序列的长度,记录最长的连续的最长序列。
首先需要将集合中的元素进行降重,降重可以想到使用哈希集合。
例: [0,3,7,2,5,8,4,6,0,1] 降重后为 [0,3,7,2,5,8,4,6,1]
① 建立哈希集合unordered_set,移除重复元素(增加查找的速度)。
② 查找最长连续序列时,首先需找到连续序列的头。判断一个元素 num 是否为序列头,可判断集合中是否存在 num - 1(哈希集合满足快速查找),若不存在 num-1 则 num 为连续序列的头。
③ 当 num 是连续序列的头时需接着判断连续序列的长度。通过判断 是否存在 num+1,num+2 … num+n。来确定连续序列的长度。
④ 通过查找各个连续序列来得出最长连续序列
例:[100,4,200,1,3,2]中从元素100开始,99不在哈希表中则100为连续序列的开始元素,连续序列长度为1。再判断4,3存在哈希表中则不记录连续长度。再判断下一个元素,依次进行下去。通过比较记录的连续长度挑选出最长连续序列。
2、复杂度分析:
① 时间复杂度:O(n),边查找边判断连续长度所以时间复杂度为O(n)。
② 空间复杂度:O(n),创建哈希表O(n)。
代码实现
代码实现(思路二(哈希集合)):
class Solution {
public:int longestConsecutive(vector<int>& nums) {// 第一步:将所有唯一的数字插入到unordered_set中unordered_set<int> num_set(nums.begin(), nums.end());// 用来追踪最长连续序列的长度int longest_streak = 0;// 第二步:遍历集合中的每一个数字for (const auto &num : num_set){// 如果集合中不存在num-1,说明num是一个连续序列的起始数字if (num_set.count(num-1) == 0){int count = 1; // 初始化当前序列的长度为1,num是序列的第一个数字// 第三步:继续检查num+1, num+2, ... 直到不连续为止while (num_set.count(num + count)){count++; // 如果num+count存在于集合中,则当前序列长度加1}// 第四步:更新最长序列长度longest_streak = max(longest_streak, count);}}// 第五步:返回最长连续序列的长度return longest_streak;}
};
以思路二为例进行调试
#include<iostream>
#include<vector>
#include<unordered_set>
#include<algorithm>
using namespace std;class Solution {
public:int longestConsecutive(vector<int>& nums) {// 第一步:将所有唯一的数字插入到unordered_set中unordered_set<int> num_set(nums.begin(), nums.end());// 用来追踪最长连续序列的长度int longest_streak = 0;// 第二步:遍历集合中的每一个数字for (const auto &num : num_set){// 如果集合中不存在num-1,说明num是一个连续序列的起始数字if (num_set.count(num-1) == 0){int count = 1; // 初始化当前序列的长度为1,num是序列的第一个数字// 第三步:继续检查num+1, num+2, ... 直到不连续为止while (num_set.count(num + count)){count++; // 如果num+count存在于集合中,则当前序列长度加1}// 第四步:更新最长序列长度longest_streak = max(longest_streak, count);}}// 第五步:返回最长连续序列的长度return longest_streak;}
};int main(int argc, char const *argv[])
{vector<int> nums={0,3,7,2,5,8,4,6,0,1}; Solution s;cout<<s.longestConsecutive(nums);return 0;
}
LeetCode 面试经典 150_哈希表_最长连续序列(47_128)原题链接
欢迎大家和我沟通交流(✿◠‿◠)