首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C++二分查找算法:132 模式枚举3

  • 25-02-22 05:00
  • 4158
  • 8394
blog.csdn.net

说明

本篇是视频课程的讲义,可以看直接查看视频。也可以下载源码,包括空源码。

本题不同解法

包括题目及代码C++二分查找算法:132 模式解法一枚举3
C++二分查找算法:132 模式解法二枚举2
代码最简洁C++二分查找算法:132 模式解法三枚举1
性能最佳C++单调向量算法:132 模式解法三枚举1

题目

给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j] 。

如果 nums 中存在 132 模式的子序列 ,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [1,2,3,4]

输出:false

解释:序列中不存在 132 模式的子序列。

示例 2:

输入:nums = [3,1,4,2]

输出:true

解释:序列中有 1 个 132 模式的子序列: [1, 4, 2] 。

示例 3:

输入:nums = [-1,3,2,0]

输出:true

解释:序列中有 3 个 132 模式的的子序列:[-1, 3, 2]、[-1, 3, 0] 和 [-1, 2, 0] 。

参数范围:

n == nums.length

1 <= n <= 2 * 105

-109 <= nums[i] <= 109

分析

分两步。

第一步计算12存储到m_v2To1。m_v2To1[j]等于i表示nums[j] >=nsum[i],如果有多个合法的i,取最小值,如果不存在,m_v2To1[j]=m_c。mValueIndex的key对应数组值nums[i],value对应数组索引i,i取[0,j)。由于是从左向右寻找小于某数的数,如果i1>=i0,且nums[i1] >= nums[i0],则i1被淘汰。淘汰后,mValueIndex中的数组值按升序排序,数组索引按降序排序。如果mValueIndex中存在数组值小于iValue的数,那说明存在值、索引都比i小的数,i被淘汰。大于等于i的索引还未添加。如果不存在,不需要判断当前值和索引是否淘汰已有值,因为:索引是按从小到大添加的。添加时需要判断当真值,是否存在。如果存在,则其索引一定小于当前索引,无需添加。

第二步,遍历m_v2To1,寻找是否存在k。mValueIndex的key对应数组值nums[k],value对应数组索引k,j取[0,i)。由于是从右向左寻找大于某数的数,所以数组值和索引都小的值和索引被淘汰。淘汰后,mValueIndex中的数组值按升序排序,数组索引按降序排序。由于mValueIndex已有数据中的索引小于当前索引,所以只需要考虑淘汰旧值(数组值小于等于当前数组值)。k需要符合以下三个条件:

条件一

nums[k] > nums[j]

条件二

k > i(即v2To1[j])

条件三

k < j (一定符合,不符合的还没添加)

auto it = mValueIndex.upper_bound(iValue);

后[it, mValueIndex.end()) 都符合条件一,由于索引是降序排序,所以只需要判断it->second是否大于i。

核心代码

class Solution {

public:

         bool find132pattern(vector<int>& nums) {

                   m_c = nums.size();

                   m_v2To1.assign(m_c, m_c);

                   {

                            map<int, int> mValueIndex;//key按升序,value按降序排序

                            for (int j = 0; j < m_c; j++)

                            {

                                     const int iValue = nums[j];

                                     auto it = mValueIndex.lower_bound(iValue);

                                      if (mValueIndex.begin() != it)

                                     {

                                               auto itPre = std::prev(it);

                                               m_v2To1[j] = itPre->second;

                                               continue;//key和value都小于等于iValue和i,i被淘汰

                                     }

                                     //删除key和value都大于等于iValue和i

                                     if (!mValueIndex.count(nums[j]))

                                     {

                                               mValueIndex[nums[j]] = j;

                                     }

                            }

                   }

                   //遍历v[2],看是否存在3

                   {

                            map<int, int> mValueIndex;//132的3,从右向左找大于2的值。key按升序,value按降序排序

                            for (int j = 0; j < m_c; j++)

                            {

                                     const int iValue = nums[j];

                                     auto it = mValueIndex.upper_bound(iValue);

                                     if (mValueIndex.end() != it)

                                     {

                                               if (it->second > m_v2To1[j])

                                               {

                                                        m_iIndex3 = it->second;

                                                        return true;

                                               }

                                     }

                                     while (mValueIndex.size() && (mValueIndex.begin()->first <= iValue))

                                     {

                                               mValueIndex.erase(mValueIndex.begin());

                                     }

                                     mValueIndex[iValue] = j;

                            }

                   }

                   return false;

         }

         vector<int> m_v2To1;//v[i]等于j表示nums[i] >=nsum[j],如果有多个合法的j,取最小值,如果不存在,v[i]=m_c。

         int m_iIndex3=-1;      

         int m_c;

};

测试用例

template<class T>

void Assert(const T& t1, const T& t2)

{

         assert(t1 == t2);

}

template<class T>

void Assert(const vector<T>& v1, const vector<T>& v2)

{

         if (v1.size() != v2.size())

         {

                   assert(false);

                   return;

         }

         for (int i = 0; i < v1.size(); i++)

         {

                   Assert(v1[i], v2[i]);

         }

}

int main()

{

         vector<int> nums;

         bool res;

         {

                   Solution slu;

                   nums = { 3,5,0,3,4 };          

                   res = slu.find132pattern(nums);

                   Assert(vector<int>{5, 0, 5, 2,0}, slu.m_v2To1);

                   Assert(1, slu.m_iIndex3);

                   Assert(true, res);

         }

         {

                   nums = { 1 ,2, 3,4 };

                   res = Solution().find132pattern(nums);

                   Assert(false, res);

         }

         {

                   Solution slu;

                   nums = { 3,1,4,2 };

                   res = slu.find132pattern(nums);

                   Assert(vector<int>{4, 4, 0, 1}, slu.m_v2To1);

                   Assert(2, slu.m_iIndex3);

                   Assert(true, res);

         }

         {

                   Solution slu;

                   nums = { -1,3,2,0 };

                   res = slu.find132pattern(nums);

                   Assert(vector<int>{4, 0, 0, 0}, slu.m_v2To1);

                   Assert(1, slu.m_iIndex3);

                   Assert(true, res);

         }

         //CConsole::Out(res);

}

https://img-blog.csdnimg.cn/ea2601b3918f4aef836b5fe30da2ebf7.gif#pic_center#pic_center

其它

学院课程

基础算法的C++实现课程,请点击下面的CSDN学院的链接。讲义有算法详解。

2024年1月15之前完全免费,之后绝大部分免费

https://edu.csdn.net/course/detail/38771

C#入职培训

此课程的目的:让新同事更快完成从学生到C#程序员的转换,更快上手完成C#的开发工作。

https://edu.csdn.net/course/detail/38768

C++入职培训

让新同事更快完成从学生到C++程序员的转换,更快上手完成C++的开发工作。

https://edu.csdn.net/course/detail/32049

运行验证环境

Win10 VS2022 Ck++17 或win7 VS2019 C++17

每天都补充正能量

好好学习,天天向上。

事无终始,无务多业。

是故置本不安者,无务丰末。

相关下载

如果你时间宝贵,只想看精华,请到CSDN下载频道下载《闻缺陷则喜算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653

https://img1.iyenn.com/thumb02/c4a7c45db2a7b21g/98031697456709977022.jpeg

文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览54934 人正在系统学习中
群中有博文配套源码
QQ群名片
注:本文转载自blog.csdn.net的闻缺陷则喜何志丹的文章"https://blog.csdn.net/he_zhidan/article/details/134362273"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top