c++算法,查找最长连续序列的思路

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值