牛客208701题:深入理解最长连续序列问题
一、问题理解
给定一个无序数组,我们需要找出其中最长的连续数字序列的长度。这里的"连续"指的是数值上的连续,而不是位置上的连续。例如,在数组[100, 4, 200, 1, 3, 2]中,最长的连续序列是[1, 2, 3, 4],长度为4。
二、暴力解法分析
最直观的解法是对数组排序,然后遍历查找最长连续序列。虽然这种方法简单,但排序的时间复杂度为O(nlogn),对于大数据量(如n=10^5)来说效率不够高。
三、优化思路
1.将所有数字存入哈希集合
2.对于每个数字,检查它是否是某个连续序列的起点
3.如果是起点,向后查找连续的数字,计算序列长度
4.记录遇到的最大长度
这种方法的时间复杂度为O(n),因为每个数字最多被访问两次(一次在哈希集合中,一次在序列查找中)。
四、关键点解释
1.为什么只检查序列起点:这样可以避免重复计算。如果一个数字不是序列起点(即存在num-1),那么它肯定已经被包含在某个更长的序列中了。
2.哈希集合的优势:提供了O(1)的查找时间,使得我们可以快速判断某个数字是否存在。
3.复杂度保证:虽然有两层循环,但内层循环只有在找到序列起点时才会执行,且每个数字最多被访问两次。
五、代码实现
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * max increasing subsequence * @param arr int整型vector the array * @return int整型 */ int MLS(vector<int>& arr) { if (arr.empty()) return 0; // 使用哈希集合存储所有数字,实现O(1)查找 unordered_set<int> num_set(arr.begin(), arr.end()); int max_length = 1; for (int num : num_set) { // 只有当num是序列的起点时才进入循环 if (num_set.find(num - 1) == num_set.end()) { int current_num = num; int current_length = 1; // 向后查找连续的数字 while (num_set.find(current_num + 1) != num_set.end()) { current_num++; current_length++; } // 更新最大长度 max_length = max(max_length, current_length); } } return max_length; } };
原创内容 转载请注明出处