c++算法,最长连续序列的思路
//查找最长连续队列的长度
/例如 6, 56, 2, 7, 23, 8, 5, 8,最长为4/
方法一:最容易想到的暴力破解法
思路:寻找连续的序列,记录每一个序列长度,直到找到一个最长的序列
问题:我怎么能够方便的找到连续的序列?这里也选择简单粗暴的方法,排序。
最终一个简单的实现如下:
int test02()
{
vector<int> vn = { 23, 8, 3, 9,1,65,7 };
sort(vn.begin(), vn.end());
int maxlen = 0;
int temMaxLen = 1;
for (int i = 1; i < vn.size(); i++)
{
if (vn[i] == vn[i - 1] + 1)
{
temMaxLen++;
}
else
{
temMaxLen = 1;
}
if (temMaxLen > maxlen)
{
maxlen = temMaxLen;
}
}
return maxlen;
}
性能分析:排序+遍历的时间复杂度 o(n*n) + o(n)
方法二:遍历的时间复杂度不可避免,那么排序是否可以去掉?
思路:遍历的过程中同时寻找最大序列,每次取出一个元素寻找相邻元素是否存在,存在的话更新对应序列的最小和最大值。因为是连续的,那么我们只需要记录队列两端的值就能得出最大的值。
问题:我们怎么知道相邻元素是否存在,以及相邻元素对应的序列呢?使用hashmap保留处理结果,然后更新所属序列最小元素的最大值和最大元素的最小值(序列两端的元素),同步更新队列最大长度,保留最大值即可
int test01()
{
vector<int> vn = { 23, 8, 3, 9,1,65,7 };
unordered_map<int, pair<int, int> > umap;
int max = 0;
for (int i = 0; i < vn.size(); i++)
{
int num = vn.at(i);
if (umap.count(num))
{
continue;
}
int low = num;
int high = num;
unordered_map<int, pair<int, int>>::iterator it = umap.find(num - 1);
if (it != umap.end())
{
low = it->second.first;
}
unordered_map<int, pair<int, int>>::iterator it1 = umap.find(num + 1);
if (it1 != umap.end())
{
high = it1->second.second;
}
umap[num].first = low;
umap[num].second = high;
umap[low].second = high;
umap[high].first = low;
if (high - low + 1 > max)
{
max = high - low + 1;
}
}
return max;
}
性能分析:unordered_map是hash map,寻找元素的时间复杂度是o(n),所以整个的复杂度变成了o(n) + o(n)