一。双指针算法
1。双指针的两种情况
1⃣️情况一:两个指针分别指向两个序列,如归并排序
2⃣️情况二;两个指针指向一个序列,如快排
2。双指针算法的通用模版
for(int i=0,j=o;i<n;i++)
{
while(j<i&&check(i,j)
{
j++;
//每道题的具体逻辑
}
}
3。利用双指针算法的解题思路:
先列出该题目暴力的解法,然后观察有无单调性,如果有的话就可以利用双指针进行时间复杂度的化简。
4。核心思想:优化到O(N)
3。思考做法:
每次看到题目先想想暴力的做法怎么写,然后再看这两个指针有无单调关系,如果有的话就套一下模版合成双指针问题同时运动,优化成N
4。具体例子
1⃣️例子一:
2。
二。位运算
1。情况分析
1⃣️情况1:求一下一个整数N,它的二进制表示里面,第K位是多少
方法:
1⃣️先把第K位移到最后一位即个位:N〉〉K
2⃣️再看个位是几,即将该数与1相与,就可以知道个位数是多少,比如一个数是X,它的个位数就是X&1
3⃣️结合一二步就可以得出这种情况的解法:
N〉〉K&1
4⃣️ 注意:
int j=0;
while( x>>j)
{
j++;
}
以上这行代码可以遍历出一个十进制数的从低位到高位的所有二进制数。因为对于十进制数而言x>>j相当于除以2的j次方,所以在while条件里如果除了之后的数不等于0的话就可以继续执行。
因此可以达到我们的预期。
2⃣️情况2:实现lowBit操作,⚠️lowBit操作就是返一个数X 的最后一位1,比如X=10010,则返回10,再比如X=1001000,则返回1000
方法:
直接用X&- X即可返回最后一位1
原因:
情况2的应用场景:
计算1的个数,我们可以每次把最后一个一找出来之后去掉,然后统计即可。
三。离散化
1。定义:对于一组值域大,个数少的数据,,有时候我们需要用数组去存他的下标,但是显然这是不可能的,因此我们要将其映射到连续的自然数中。这个过程就叫做离散化
2。离散化遇到的两个问题:
1⃣️起初数组里面有重复元素,所以离散化的时候要去重
解决:利用unique函数然后再erase一下即可
2⃣️如何算出原数据离散化后的值
通过二分求出X对应的离散化值
解决:用二分法,从左往右找第一个大于等于先X 的位置
3。注意事项:在JAVA 中,vector也可以用,但是没有UNIQUE 和erase函数
unique函数即去重函数的Java实现:
其实就是利用双指针算法,将全部不重复的元素放在前面,然后返回前面不重复的就行
四。区间合并
1。定义:将所有有交集(端点也算)的区间进行合并合并成一个新的区间.
2。步骤
1⃣️按照区间的左端的排序从小到大
2⃣️扫描整个区间,扫描过程中把可能出现交集的区间进行合并,做法:每次都维护一个当前的区间,那么当扫描到第I 个区间的时候,这个区间和我们已经维护的区间只有如下的三种关系:
那么对于第一种情况,则当前区间不需要不需要变化,对于第二种情况,则当前区间要向右扩大非交集的地方,对于第三中情况,则可以肯定当前维护的这个区间已经是最大的合并了,因为第三种情况,我们是按照左端点从小到大排序的,所以第三种情况后面的区间都是左端点比第三种情况的还要没交集,所以当遇到第三种情况的时候就可以肯定了。然后接着就把第三个区间看成新的要维护的区间,上一个的维护区间就可以输出了,然后继续找下一个可以合并的区间。
实例分析
3。代码
1⃣️在代码中:会用到sort函数,这个函数是先以左端点排序,若相同,则再用右端点排序
2⃣️-2e9指的是-2的九次方即负无穷大