双指针/位运算/离散化/区间和并

这篇具有很好参考价值的文章主要介绍了双指针/位运算/离散化/区间和并。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 双指针

    • 两个指针指向两个不同的序列
    • 两个指针指向同一个序列(归并排序,快速排序)
    • 主要作用:将暴力O(n^2)遍历通过两个指针的某种单调性质优化到O(n),也就是说将内层循环变量j通过与外层循环变量i的关系,将内层循环次数降低不定次
    • 模板:

      for(int i = 1; i < n; ++ i){
      	while(j < i && check(i, j)) j ++ ;
      	//内部逻辑具体分析
      }
      
      //例如将一个字符串中的单词按行输出
      str = "acv adf wers";
      int len = strlen(str);
      //双指针算法
      for(int i = 0; i < len; ++ i){
      	int j = i;
      	while(j < len && str[j] != ' ') j ++ ;
      	
      	//内部逻辑具体分析
      	//输出单词
      	for(int k = i; k < j; ++ k) cout << str[k];
      	cout << endl;
      	int i = j;
      }
      
  • 位运算

    • 常用操作:

      • 求n的二进制的第k位:
        • 将n右移k位 (n >> k)
        • 再取右移k位后的个位 (n >> k) & 1
      • 返回x的二进制中最后一位1的位置:
        • lowbit(x) = x & -x lowbit(x)的二进制中只有一个1,该1就是x的二进制中的最后一位1
        • -x = ~x + 1 补码为反码加一
      • 求n的二进制中1的个数:
        • while(n) n -= lowbit(n), ans++;
        • 当n不为0时,n每次去掉最后一位1,ans即为n的二进制中1的数量
  • 离散化

    • 将无限区间中的有限元素映射到有限的区间中,将稀疏空间变得稠密
    • 不改变元素间的相对位置
    • 模板:

      vector<int> alls;//离散化数组
      sort(alls.begin(), alls.end()); //排序
      alls.erase(unique(alls.begin(), alls.end()), alls.end()); //去重
      //根据原值查找离散化后的下标
      int find(int x){
      	int l = -1, r = alls.size();
      	while(l + 1 < r){
      		int mid = l + r >> 1;
      		if(alls[mid] >= x) r = mid;
      		else l = mid;
      	}
      	return r + 1; //以1作为起点下标
      }
      //unique函数双指针实现
      //在不递减的数列中快速提取出不重复的数
      vector<int>::iterator unique(vector<int> &a){
      	for(int i = 0, j = 0; i < a.size(); ++ i){
      		if(!i || a[i] != a[i - 1]) //要么是第一个数,要么前一个数不同于后一个数
      			a[j ++ ] = a[i]; //a[0] ~ a[j - 1] 是所有不同的数
      	}
      	return a.begin() + j;
      }
      
      
  • 区间和并

    • 把有有交集的区间合并
    • 将所有区间按左端点从升序排列
    • 遍历所有区间,每次比较相邻两区间是否相交,若前面区间的右端点严格小与后面区间的左端点即为不相交,否则相交
    • 若两区间相交就取并集,否则得到一个合并完成的区间,更新维护的区间,进行下一次合并
    • 模板:

      typedef pair<int, int> PII; 
      vector<PII> segs; //存储不同区间
      //合并区间的函数
      void merge(vector<PII> &segs){
      	vector<PII> res; //存储答案区间
      	sort(segs.begin(), segs.end()); //默认按first升序排序
      	int st = -inf, ed = -inf; //维护的区间初始化
      	for(auto seg : segs){ //遍历所有区间
      		if(ed < seg.first){ //如果维护的区间与新区间不相交说明维护的区间已经合并完成
      			if(st != -inf) res.push_back({st, ed}); //将合并完成的区间存储
      			st = seg.first, ed = seg.second; //更新维护的区间
      		}else ed = max(ed, seg.second); //否则取交集
      		if(st != -inf) res.push_back({st, ed}); //所有区间合并成为一整个区间的情况
      		swap(res, segs); //返回答案到原数组
      	}
      }
      

文章来源地址https://www.toymoban.com/news/detail-605584.html

到了这里,关于双指针/位运算/离散化/区间和并的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C/C++】 常量指针,指针常量、指向常量的常指针详解

    指针就是指向变量在内存中的地址 数据是存放在内存中的,每一个变量都有一个内存地址,假设是一个int类型变量 a ,占4个字节的内存区,那么在内存中如果是小端方式存储,我们创建指针p,把a的地址赋值给 p ,就是把a的首地址0x1100赋值给指针 p ,这个时候p的值就是变量

    2024年02月13日
    浏览(43)
  • 8.5 【C语言】指向函数的指针

    每次调用函数时都从该地址入口开始执行此段函数代码。函数名代表函数的起始地址。 例8.22 用函数求整数a和b中的大者 解题思路:在主函数调用max函数,除了可以通过函数名调用外,还可以通过指向函数的指针变量来实现。 (2)通过指针变量调用它所指向的函数 类型名(

    2024年02月11日
    浏览(30)
  • 指向未来: 量子纠缠的本质是一个指针

    量子纠缠 (Quantum Entanglement) 是量子系统重两个或多个粒子间的一种特殊连接, 这种连接使得即使相隔很远, 这些粒子的状态也仍然互相依赖. 在探讨量子纠缠之前, 我们先阐述量子比特 (Qubit)的基本概念. 位 (Bit) 是信息的基本单位, 可以处于 0 或 1 的状态. 而量子比特可以同时处

    2024年01月19日
    浏览(83)
  • 不允许指针指向不完整的类类型

    问题原因 1:没有包含对应结构体的头文件 解决办法 1:直接添加相对应的头文件 问题原因 2:对应的结构体定义写在了C/CPP文件里 解决办法 2:将结构体定义写在对应的头文件中

    2024年02月07日
    浏览(36)
  • 【C/C++】父类指针指向子类对象 | 隐藏

    创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡𖥦)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 🔥c++系列专栏:C/C++零基础到精通 🔥 给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ c语言内容💖:

    2024年02月11日
    浏览(41)
  • 算法基础模板 快排、快选、归并、二分、离散化、区间合并、链表、图搜索、最短路等

    解决逆序对数量问题,即 if arr[i]arr[j]:res += mid - i + 1 时间复杂是 O ( n 2 + m ) O(n2+m) O ( n 2 + m ) , n n n 表示点数, m m m 表示边数 时间复杂度 O ( m l o g n ) O(mlogn) O ( m l o g n ) , n n n 表示点数, m m m 表示边数

    2024年02月13日
    浏览(42)
  • 不要轻易定义指向std::vector中的元素的指针

    类应该是被封装的,类的用户通过接口使用类提供的功能,而不必关心类的内部如何实现。然而,C++标准库容器 std::vector 的实现渗透到了接口中来。对于以下代码: 我们初始化了一个有3个int元素的vector,定义了一个int 指针p,指向v[1] , 打印 *p 以及v[1] 的值。 然后向 v 中pu

    2024年02月05日
    浏览(40)
  • 8.8 【C语言】动态内存分配与指向它的指针变量

    栈:全局变量和局部变量,全局变量是分配在内存中的静态存储区的,非静态的局部变量是分配在内存中的动态存储区的。 堆:数据临时存放在一个特别的自由存储区。 对内存的动态分配是通过系统提供的库函数来实现的,主要有malloc,calloc,free,realloc这四个函数。 1.用mallo

    2024年02月11日
    浏览(43)
  • 表达式必须包含指向对象的指针类型,但他具有“int“?

       xdm,今天在写逆序函数的时候遇到了这样一个问题——表达式必须包含指向对象的指针类型,但他具有\\\"int\\\"?原来问题出在这里...    首先来看看题目   就在第三个函数的时候,我遇到了以下这样的问题   一个简单的逆序函数逻辑没出错,那一定是哪里输入错误,通过警告

    2024年02月16日
    浏览(43)
  • C++笔记之基类指针动态地指向某一个子类情况列举

    code review!

    2024年02月12日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包