首页 > 编程语言 >第一章 基础算法三

第一章 基础算法三

时间:2023-02-12 23:00:44浏览次数:52  
标签:end int lowbit 基础 第一章 离散 算法 数组 区间

双指针

类型:

  • 2个指针指向不同的序列,比如归并排序
  • 2个指针指向同一个序列,用的比较多,比如快速排序

Image

通用模板

俗称的枚举右端点,遍历左端点

    for (int i = 0, j = 0; i < n; i++) {
        while (j < i && check(i,j)) j++;
        // 每道题的具体逻辑
    }

核心思想

对于形如

for(int i = 0; i < n; i++) {
    for(int j = 0; j < n; j++) {

    }
}

这一类的双层暴力循环,可能可以使用双指针来进行优化,从而能够把时间复杂度从O(n^2)降低到O(n)

位运算

  • 获取一个数二进制的第k位:x >> k & 1即,先将x右移k位,然后和1做与运算

  • 获取一个数的二进制的最后一位1:lowbit(x) = x & -x

    例如 x = 1010 lowbit(x) = 10, x = 101000 lowbit(x) = 1000

    lowbit运算的原理是,x & -x,由于-x采用补码表示,它等于对x的原码取反再加1,即-x = ~x + 1比如 x 的二进制表示是:

    100101000,对x取反得

    011010111,加1得

    011011000所以x & (~x + 1),则x的最后一位1,被保留了下来,这个位置后面,两个数全是0,这个位置前面,两个数是取反,做与运算后也全为0。lowbit的最简单的应用:统计x的二进制表示中,1的个数。具体的实现方式是:每次对x做lowbit运算,并将运算结果从x中减去。循环做下去,直到x被减为0,一共减了多少次,x中就有多少个1。

离散化

有的数组,其元素的值域很大,比如数组中的元素取值都是[0, 10^9],但元素的个数很少,比如只有1000个元素。

有时(例如计数排序的思想),我们需要将元素的值,作为数组的下标来操作。此时不可能开一个10^9大小的数组。此时我们把这些元素,映射为从0(或者从1)开始的自然数。(也可以理解为对稀疏数组进行压缩)

例子如下:

有一个数组a,[1, 3, 100, 2000, 500000](已经排好序),我们把这个数组中的元素,映射为[0, 1, 2, 3, 4],这个映射的过程,称之为离散化

离散化有2个要点:

  • 原数组a中若有重复元素,可能需要去重
  • 如何根据a[i],算出其离散化后的值:由于原数组已经排好序,故这里用二分查找即可

代码模板

vector<int> v; // 待离散化的数组
sort(v.begin(), v.end()); // 将数组先排序
v.erase(unique(v.begin(), v.end()), v.end()); // 对数组进行去重
// 进行离散化, 将数组的值依次映射到 0,1,2,3,4,5, ... 等自然数

// 根据数的值, 求出其离散化的值
int find(int x) {
    int l = 0, r = v.size() - 1;
    while(l < r) {  // 找到第一个大于等于x的离散化的值
        int mid = l + r >> 1;
        if(v[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return r + 1; // 是否加1, 跟题目相关, 若是前缀和差分等需要下标从1开始, 则需要加1
}

区间合并

给定很多个区间,若2个区间有交集,将二者合并成一个区间

做法思路:

  1. 先按照区间的左端点进行排序
  2. 然后遍历每个区间,进行合并即可维护一段区间,对于区间 i,可能有下面几种关系:

Image

  • 对于第一种情况,区间不变
  • 对于第二种情况,end要变成区间i的右端点前面两种情况,可以合并为将end更新为end和区间i的右端点中的较大者
  • 对于第三种情况,将当前维护的区间加入答案,并将维护的区间更新为区间i

标签:end,int,lowbit,基础,第一章,离散,算法,数组,区间
From: https://www.cnblogs.com/chenjq12/p/17114939.html

相关文章

  • 第一章 基础算法一
    第一章基础算法一快速排序quick_sort(intq[],intl,intr)q是待排序数组,l是待排序区间的左边界,r是右边界确定分界点x,可以取左边界的值q[l],或右边界的值q[r],或者中......
  • 基于Astar算法的栅格地图目标最短路径搜索算法MATLAB仿真,带GUI界面
    1.算法描述       Astar算法是一种图形搜索算法,常用于寻路。它是个以广度优先搜索为基础,集Dijkstra算法与最佳优先(bestfit)算法特点于一身的一种算法。它通过......
  • 第一章 基础算法二
    高精度A+B:两个大整数相加A-B:两个大整数相减A×b:一个大整数乘一个小整数A÷b:一个大整数除以一个小整数大整数的存储:用一个数组来存大整数的每一位上的数。这......
  • 基于GA算法的TSP最短路径搜索matlab仿真
    1.算法描述(1)编码:将问题的候选解用染色体表示,实现解空间向编码空间的映射过程。遗传算法不直接处理解空间的决策变量,而是将其转换成由基因按一定结构组成的染色体。编码方......
  • 调度算法2
    调度算法21、时间片轮转调度算法(RR,Round-Robin)2、优先级调度算法非抢占式抢占式3、多级反馈队列调度算法知识回顾......
  • BF算法与KMP算法
    1.BF算法BF算法,即暴力(BruteForce)算法,是普通的【模式匹配】算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二......
  • Qt基础知识学习
    UI界面层(view)——>控制器层:当用户操作UI界面时,发射一个控制器层信号;控制器层(controller)——>模型层:控制层调用模型层功能函数,实现对应业务逻辑功能;模型层(model)——>控制器层......
  • 《分布式技术原理与算法解析》学习笔记Day09
    非集中式结构什么是非集中式结构?在非集中式结构中,服务的执行和数据的存储被分散到不同的服务器集群,服务器集群之间通过消息传递进行通信和协调,非集中式结构没有中央服务......
  • linux 基础(8)例行任务
    我们的linux系统,有时会自动进行线上更新,会定时升级locate用到的数据库。用户也会“在每天0点备份数据”或者“每天8点分析登录文件”,管理这些例行任务就叫做“工作调度”......
  • Java基础知识点(if语句的第二种和第三种)
    一:if语句的第二种格式1.格式:if(关系表达式){语句体1;​}else{语句体2;}2.执行流程:1.首先计算关系表达式的值。2.如果关系表达式的值为true,就执行语句体1.3.如果关系表达式的值......