首页 > 其他分享 >双指针/位运算/离散化/区间和并

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

时间:2023-07-26 22:11:26浏览次数:37  
标签:运算 int ed 离散 ++ alls 区间 指针

  • 双指针

    • 两个指针指向两个不同的序列
    • 两个指针指向同一个序列(归并排序,快速排序)
    • 主要作用:将暴力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); //返回答案到原数组
      	}
      }
      

标签:运算,int,ed,离散,++,alls,区间,指针
From: https://www.cnblogs.com/moilip/p/17583670.html

相关文章

  • 问题--链表指针传参,修改next指针只传值
    1.问题--链表指针传参,修改next指针只传值Link_creat_head(&head,p_new);//将新节点加入链表在这当中head头指针传的是地址,而p_new传的是值,这二者有什么区别?#include<stdio.h>#include<stdlib,h>//定义结点结构体typedefstructstudent{//数据域intnum;......
  • C++使用指针进行地址传递及错误示范
    正确示范:voidchange(int*a,int*b){ inttemp=*a; *a=*b; *b=temp;}错误示范:voidchange(int*a,int*b){ int*temp=a; a=b; b=temp;} ......
  • cpp: 指针赋值
      char*pp=newchar[100]; chard[100]="geovindu,涂聚文"; stringddstr="geovindu,涂聚文"; char*dstr=nullptr; pp=d; dstr=&ddstr[0]; printf(dstr); printf(pp); printf("\n"); ......
  • 运算符
    运算符Java语言支持如下运算符:算术运算符:+,-,*,/,%,++,--赋值运算符:=关系运算符:<,>,<=,>=,==,!=,instanceof逻辑运算符:&&,||,!位运算:&,|,^,~,>>,<<,>>>条件运算:扩展复制运算符:+=,-=,*=,/=publicclassnote02{publicstaticvoidmain(St......
  • 1.变量与运算符
    1.关键字(keyword)定义:被Java语言赋予了特殊含义,用做专门用途的字符串(或单词)HelloWorld案例中,出现的关键字有class、public、static、void等,这些单词已经被Java定义好了。特点:全部关键字都是小写字母。关键字比较多,不需要死记硬背,学到哪里记到哪里即可。官方地......
  • 初识C数据结构之“*”和“&”(指针、解引用、取地址、引用)
    这天小阿杰又在看C数据结构——顺序表中几个传参的小小的内容引起了小阿杰大大的疑惑:(教材为严蔚敏老师的《数据结构(C语言版第2版)》)可怜的小阿杰当时只知道&取地址……后来查阅资料才对其中略知一二,那咱们下面就来唠唠。顺便提一下,引用&只在C++中有,C语言......
  • PHP 运算符
    PHP算数运算符运算符名称例子结果+加法$x+$y$x与$y求和-减法$x-$y$x与$y的差数*乘法$x*$y$x与$y的乘积/除法$x/$y$x与$y的商数%取模$x%$y$x除$y的余数下例展示了使用不同算数运算符的不同结果:实例<?php$x......
  • 指针day1
    指针一:指针代码示例B站视频代码#include<stdio.h>intmain(){ inta=1025; int*p; p=&a; printf("sizeofintegeris%dbytes\n",sizeof(int)); printf("Address=%d,value=%d\n",p,*p); printf("Address=%d,value=%d\n&......
  • leetcode第354场周赛 2 - 双指针
    题目传送门2779.数组的最大美丽值题意给你一个数组和一个整数k,数组里面每个数都只能操作一次:加上区间\([-k,k]\)里的数。问你最终由相等元素组成的最长子序列的长度双指针的妙用!思路先排序,前后双指针取差值在2k之间的区间,此区间的所有数均可以操作为同一个属,ans统计最大值......
  • 析构函数虚表指针回填问题
    1问题提出笔者偶然发现对于含有虚函数的类,析构函数也会更新虚表指针。小有所得,特此记录。这里使用vs202232位debug作为实验环境。对于一个有虚函数的类,编译器在生成构造函数时,不只生成我们自己写的虚构函数里面的语句,还会把虚表地址赋值到对象中。比如如下类,构造函数里面根......