第一章 基础算法(三)
双指针算法
第一类,两个指针分别指向两个序列(归并排序)
第二类,两个指针指向一个序列(快速排序的划分的过程)
基本上双指针算法的通用模板
1 | for(i = 0, j = 0; i < n; i++){//i整个扫描一遍 |
虽然循环长成这个样子,看上去是两重循环,但是每一个指针在所有循环里面总共的移动次数是不超过n的,两个指针的总共移动次数就不超过2 * n
==双指针算法最核心的性质就是可以将下面的朴素算法优化到O(n).我们运用了某些性质, 本来要枚举O(n * n)种情况,现在只需要枚举O(n)种情况==
核心思想:
1 | for (int i = 0; i < n; i ++) |
时间复杂度是O(n * n)
但是所有的双指针算法,时间复杂度是O(n)的
举一个例子:输入一个字符串,然后我们要把其中的每一个单词输出出来,单词与单词之间是用一个空格隔开的.
自己的写法
1 |
|
个人感觉:因为这都是低级的算法课,真正的高级算法都是不让你写代码,都是给你伪代码,直接让你证明这种算法的正确性,或者让你自己设计一个正确的伪代码步骤并让你证明.高级的都是考察你的数学证明,太难了.
反正我是学习低级的,因此更多的还是靠别人讲了一个遍,我背下来,遇到新题就照猫画虎的模仿然后改写,遇到不会的就背新的.然后就是我刚刚这样子,在学新课的时候,想着自己想写一遍,不求能够数学上完全相信自己是对的,知道大概意思就够了,时间不够,不如多背点稳定做出来的题目.
[!NOTE]
备注:
自己一段时间没学习,写的时候竟然只记得char s[] 的getline的写法,忘记了string s 的getline写法.查阅自己的笔记之后才会想起来,可见记笔记是一件很重要的事情.笔记如下
https://hsuwindow.vip/cshsuwindowDIY/C/grammar/C++PrimerPlusStudyNotesCh4/
char s[N]
的getline的写法记忆
1 cin.getline(s, N);这里cin是对象,调用对象类的函数用.运算符连接起来,加上第一个参数是数组名字,第二个参数是最多读取的字符数,当然一般是你定义的数组的ArSize.最终构成了上面的写法.
string s
的getline写法记忆
1因为string s 的写法在char s[]后面出现,因此cin.getline()的第一个参数没有重载成C++String类型的字符串,因此直接调用getline函数.(这一段是我模糊的听课的记忆,有可能是错的,但是能帮助我记忆回想就是好的).getline函数里面第一个参数是从哪里读入,当然是从键盘的标准输入流读入(我这么记得标准输入流是stdin,这里自己也可能记错了,但是能帮助自己记忆就好),所以是cin,第二个参数就是字符串 的名字s了.
y总的写法
1 |
|
这和我们的模板基本上是对应上的,可以在
1 | while (j < i && check(i, j))//每次i更新完之后,我们要更新我们的j |
上面做一些小改动,然后是写这道问题的具体逻辑.(写具体逻辑的时候还是要笔和草稿纸,自己刚刚没有笔和草稿纸脑袋有非常的混乱,什么都记不清楚)
1 | for(i = 0, j = 0; i < n; i++){//i整个扫描一遍 |
模板就是为了帮助大家来节省时间.
凡是有这样==形式==的,都可以被称作双指针算法.核心思想就是可以吧本来要枚举O(n * n)种情况,枚举i , j两种循环.我们从中挖掘了某种性质,让我们利用这种性质只需要枚举O(n)种情况.凡是有这样性质的题目都可以被称作双指针算法.包括我们之前讲 的快排,或者归并排序的归并那一步,还有明天要将的kmp算法都是一个这样的问题.
看一个新的问题,就是打卡题
AcWing 799. 最长连续不重复子序列
一个自己的小技巧,就是对公差为1 的等差整数数列.求区间[a, b]或者区间[a, b)之间有多少个数字.例如0,1 ,2 就有三个数字.自己总结的公式如下
1 | //记忆口诀: |
自己的写法
说实话,我红温了,自己用动脑袋就头疼,以后再也不动闹了.他们的东西我果然看不懂,我是个笨蛋
check函数写不对,我开摆了,以后我动脑我就给自己一巴掌,还不赶紧去背诵自己可能会的.
1 |
|
涉及到找重复数字,有一篇博客
AcWing 800. 数组元素的目标和
AcWing 2816. 判断子序列
位运算
AcWing 801. 二进制中1的个数29601人打卡
离散化
AcWing 802. 区间和24287人打卡
区间合并
AcWing 803. 区间合并25423人打卡
DONE
==最终的记忆还是要看文字描述的思路,然后自己慢慢回忆起来代码是怎么写的.要有从精简的文字概括到复现代码的过程才能记得牢靠.==
这一节的笔记就到这里了.学完之后立马自己重新写一遍还是很有效果的.以后要一直坚持,然后复习的时间规律我之后再说.