最长连续序列,leetCode热题100,C++实现
题目来源:leetCode
128. 最长连续序列 - 力扣(LeetCode)
解法
class Solution {
public:int longestConsecutive(vector<int>& nums) {if (nums.empty()) return 0;unordered_set<int> numSet(nums.begin(), nums.end());int maxLength = 0;for (int num : numSet) {// 只有当当前数字是序列的起点时才检查if (numSet.find(num - 1) == numSet.end()) {int currentNum = num;int currentLength = 1;// 查找连续序列while (numSet.find(currentNum + 1) != numSet.end()) {currentNum++;currentLength++;}maxLength = max(maxLength, currentLength);}}return maxLength;}
};
前面是判空和创建,我们直接来看重点for循环,我们遍历set,然后查找起点
什么是起点?假设数组里为{1, 2, 3, 4, 100, 200},那么1就是起点,因为1的前面没有数字,比如我查找0,就是不存在,所以1是起点,同理100和200也是起点
numSet.find(num - 1) == numSet.end()
是在set里查找key,如果找到则返回该元素迭代器,如果没找到则返回numSet.end()
numSet.end()是什么?
它不是指向最后一个元素,而是指向最后一个元素之后的位置
可以理解为"结束标志"或"无效位置"
类似于字符串的
'\0'
结束符
可以理解为如果没找到就会返回numSet.end()
进入if语句里面,首先是创建两个变量,一个是长度,一个用于保存当前数字,然后我们看while
while用于检测下一个数字是否存在
如果存在则当前数字+1,长度+1,最后再比较长度即可
下面我简单说一下整体逻辑,方便理解
首先是判断数组为空,然后是创建set,接着是for循环遍历set,然后是for里面循环逻辑,首先看看当前数字的前一个数是否存在,比如当前数字为2,就查看1是否在set里存在,如果存在则不是起点,跳过,如果不存在,说明是起点,进入if语句,创建长度变量和num,然后开始进行while循环,如果当前数字的下一位存在,则继续循环,比如当前数字为2,查找3是否存在,如果存在,则num++,num变成3,然后长度也同样+1,接着判断maxlength,最后然后maxlength
时间复杂度也是符合,每个数字最多被访问2次,也就是O(2N),符合O(N)