class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> num_set;
for (const int& num : nums) {
num_set.insert(num);
}
int longestStreak = 0;
for (const int& num : num_set) {
if (!num_set.count(num - 1)) {
int currentNum = num;
int currentStreak = 1;
while (num_set.count(currentNum + 1)) {
currentNum += 1;
currentStreak += 1;
}
longestStreak = max(longestStreak, currentStreak);
}
} return longestStreak;
}
};
这个函数的目的是找出一个未排序整数数组nums
中最长连续子序列的长度。
-
定义函数和参数:
longestConsecutive
函数接受一个vector<int>& nums
作为参数,这表示一个整数类型的向量,它可能包含重复的数字。
-
创建一个哈希表(unordered_set):
- 在函数内部,首先创建了一个
unordered_set
类型的变量num_set
,用于存储数组中的独特元素。使用unordered_set
可以快速检查一个元素是否存在于集合中,时间复杂度为O(1)。
- 在函数内部,首先创建了一个
-
初始化最长连续序列长度变量:
- 定义了一个名为
longestStreak
的整数变量,用于记录最长连续序列的长度。初始值设为0。
- 定义了一个名为
-
遍历哈希表中的元素:
- 使用一个for循环遍历
num_set
中的每个元素。这里使用const int&
是为了以常量引用的方式访问集合中的元素,这样可以避免不必要的拷贝。
- 使用一个for循环遍历
-
检查连续序列:
- 对于
num_set
中的每个元素num
,代码首先检查num - 1
是否存在于num_set
中。如果不存在,说明num
是连续序列的起始元素。 - 接下来,定义了两个变量
currentNum
和currentStreak
,分别用于跟踪当前检查的连续序列的第一个元素和该序列的长度。 - 使用一个while循环,检查
num_set
中是否存在currentNum + 1
的元素。如果存在,说明当前序列可以继续延长,更新currentNum
和currentStreak
的值。 - 循环结束后,使用
max
函数更新longestStreak
的值,使其成为当前找到的最长连续序列长度和之前记录的最长序列长度中的较大值。
- 对于
-
返回结果:
- 遍历完成后,函数返回
longestStreak
,即数组中最长连续子序列的长度。
- 遍历完成后,函数返回
这个算法的时间复杂度是O(n),其中n是数组nums
的长度。这是因为每个元素最多只会被访问两次:一次是在构建哈希表时,另一次是在检查连续序列时。空间复杂度是O(n),因为哈希表存储了数组中的所有唯一元素。
num_set.insert(num)
和 num_set.count(num)
是 C++ 中 std::unordered_set
容器的两个成员函数,它们用于管理和查询集合中的元素。
-
num_set.insert(num)
:- 这个函数用于将一个元素插入到
unordered_set
容器中。 insert
函数有几种不同的重载版本,但在这个上下文中,num
是要插入的元素的值。- 如果
num
已经存在于集合中,insert
函数不会再次插入它,因为集合不允许重复元素。在这种情况下,insert
操作不会改变集合的内容,但它会返回一个pair
类型的对象,其中第一个元素是unordered_set
的迭代器,指向已存在的元素,第二个元素是一个布尔值,表示是否插入了新元素(在这个例子中是false
,因为元素已经存在)。 - 如果
num
不在集合中,它会被插入,并且insert
函数会返回一个包含指向新插入元素的迭代器和true
的pair
对象。
- 这个函数用于将一个元素插入到
-
num_set.count(num)
:- 这个函数用于查询
unordered_set
容器中是否存在某个特定的元素。 count
函数接受一个参数,即要查找的元素值。- 它返回一个大小为 0 或 1 的整数值,表示集合中是否存在该元素。如果元素存在,返回 1;如果不存在,返回 0。
- 这个函数非常有用,因为它可以在常数时间复杂度 O(1) 内告诉你一个元素是否是集合的一部分,而无需遍历整个集合。
- 这个函数用于查询
在提供的代码示例中,num_set.insert(num)
被用于创建一个包含 nums
数组中所有唯一元素的集合。而 num_set.count(num - 1)
被用于检查当前元素的前一个数字是否存在于集合中,这是为了确定当前元素是否可以开始一个新的连续序列。如果 num - 1
不存在,那么当前元素是连续序列的起始点。