中级提升班1

image.png

image.png

考点:后序建立二叉树,查找优化(root节点的过程,N-> log2N)

image.png
image.png
考点:滑动窗口、固定长度(和目标串长度一致),所有字符都存在的统计

image.png
初始思路:滑窗长度L
image.png

image.png
image.png
先尝试拿最多的8,然后剩余部分拿6,一旦剩余部分大于8,6的最小公倍数24,结束尝试
image.png

image.png
image.png

image.png
优化:
辅助数组从左往右统计记录 0~i范围上有多少个R
辅助数组从右往左统计记录 j~Len-1范围上有多少个G

image.png
初始思路:暴力法,尝试矩阵上的每个点O(nn),再尝试正方形边长O(n),最终复杂度O(nnn)
image.png
推荐思路:辅助存储
right[i][j]: 对应原始矩阵arr[i][j]位置 右侧(包含自己)有多少个连续的1
down[i][j]: 对应原始矩阵arr[i][j]位置 下方(包含自己)有多少个*连续
的1
image.png
image.png
image.png

image.png

推荐思路:现将f(1~5),还原成一个0,1等概率发生器即:01发生器 random01(),然后利用所有数字都可以用二进制表示,利用01发生器生成2进制串即可,

例如:1~7,等价于0~6的随机数,最多有3位二进制数,将超出的部分7舍弃掉重做即可,
例如:5~13,等价于0~8的随机数,需要4位二进制数,如果生成9~15部分则重做即可
image.png

p概率产生0,1-p产生1,利用生成01的概率p(1-p)和生成10的概率(1-p)p相等,生成返回0,1。其他情况00,11舍弃重做
image.png

image.png
先穷举,再动态规划,假设左子树有i个节点,那么右子树就有n-i-1个节点
左程云 leetcode题 - 图22
eg:
n=0, f(0)=1
n=1, f(1)=1
n=2, f(2)=f(0)f(1)+f(1)f(0)
n=3, f(3)=f(0)f(2)+f(1)f(1)+f(2)f(0)
n=5, f(5)=f(0)
f(4)+f(1)f(4)+f(2)f(2)+f(3)f(1)+f(4)f(0)

image.png
暂无思路,后续再看

中级提升班2

image.png
初始思路:先排序,然后滑窗计算
[3,2,5,7,0,0],k=2
推挤思路:哈希表,类似两数之和的题,遍历一遍生成哈希表,第二次遍历第一个数3时,查找有没有1或者5存在即可

image.png

image.png
初始思路:类似于走楼梯,每次可以走一步或者两步,
f(n)=f(n-1)+f(n-2)

递归版本:
image.png
动归版:
image.png

image.png
动归:dp[i]=以i结尾的最长匹配
d[i]=d[i-1]+2+dp[i-d[i-1-2]]

image.png

image.png

image.png
推荐思路:递归尝试
image.png
另解,找规律
image.png

image.png
初始思路:先序遍历,累加路径,直到叶节点,比较左右子树最大值

中级提升班3

image.png
初始思路:先排序从大到小,右边大的-1,左边小的+1

推荐思路:
对于第i个机器单独考虑,
左边应得多少件,实际有多少件,差多少件
右边应得多少件,实际有多少件,差多少件

image.png
image.png
image.png
return ans;

image.png
推荐思路:定义两个点,a,b初始均为(0,0),a往下走,b往右走,每各走一步,输出打印a-b斜线上的数据,通过boolean变量取反交替控制打印a->b的上的数据和b->a的数据,a走到头往右,b走到头下,直到再次走到头结束
image.png
image.png
image.png

image.png
初始思路:按 右下左上 ,4种变相方式进行变换,每遇到边界或者已经访问过的(记录访问矩阵)变换一次相位
推荐思路:
设计一个基础函数,给定两个点打印这两个点组成的长方形边框
初始两个点(0,0)(m,n),打印完成后各沿对角线移动一位(1,1)(m-1,n-1)
继续打印边框,直到长方形边界重合
image.png
image.png

image.png
image.png
image.png
image.png

image.png
初始思路:递归走迷宫穷举所有可能

取巧思路:
image.png
变种:01矩阵中,每一行0横在1左边,求1最多的行索引
image.png
初始思想:二分取列,看列中是否有1,如果有就在[0~left]中继续二分

取巧思路:
image.png

image.png
和质数有关的题,先跳过,直接记结论:所有质数因子(不含1)的和 - 因子的个数
image.png

image.png
初始思路:堆排序
推荐思路:hash+小根堆+map

另外:PriorityQueue类实现了优先队列,默认是一个小根堆的形式,如果要定义大根堆,需要在初始化的时候加入一个自定义的比较器。
PriorityQueue 实现heap
minHeap:PriorityQueue默认实现小根堆,待 PriorityQueue 实战演练

待重听记录笔记

小根堆

PriorityQueue类实现了优先队列,默认是一个小根堆的形式,如果要定义大根堆,需要在初始化的时候加入一个自定义的比较器。
https://blog.csdn.net/Awt_FuDongLai/article/details/115492987?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-1.no_search_link&spm=1001.2101.3001.4242.2

java集合类TreeMap和TreeSet及红黑树

中级提升班4

image.png
两个队列,每条数据加上时间戳就行
image.png
推荐思路:维护两个栈,一个存放数据data栈,一个存放最小值min栈,
push操作时,判断待push元素和min栈顶元素哪个小,谁小min栈压入谁
pop时,data弹出一个,min就弹出一个
image.png

扩展min队列,最小值队列
https://blog.csdn.net/qiwoo_weekly/article/details/96416070

推荐思路:数据队列data,最小值队列min,队尾进,队首出
入队x元素:
data:x元素队尾进
min:如果x小于min队尾,min队尾弹出,直到x大于等于min队尾,x队尾进入

出队:
data:队首y元素出队
min:如果y==min的队首,min队首弹出,否则min不作操作

特殊情况:重复值
data:1,1,3,3,2,2
min:1,1,2,2

image.png

image.png
两个栈实现队列:
入队列时:进push栈,
出队列时:如果pop栈无数据,将push栈中的数据全部倒出入pop栈
如果pop有数据时,不能push->pop迁移数据操作
image.png
两个队列实现栈:
image.png
入栈时:先进队列1,
出栈时:队列1中留一个元素,其余全进入队列2,弹出队列1中的最后一个元素,此时队列1空了,
再次弹出时,队列2留一个元素其余全进队列1,弹出队列2的最后一个元素,此时队列2空了,继续下去

image.png

image.png
image.png
image.png
image.png
推荐思路:
此问题变成了求数组每个元素左侧部分的最大值,以及右侧部分的最大值的题目

速记方法:两个辅助数组求两侧最大值
扫描数组从左到右,辅助数组leftMax依次求出记录第i个位置的左侧最大值
扫描数组从右到左,辅助数组rightMax依次求出记录第i个位置的右侧最大值

左程云 leetcode题 - 图70

优化思路:无需辅助数组,降低空间占用,单调栈(不一定行)
双指针:
image.png

image.png
初始思路:预处理,辅助数组

两个辅助数组求两侧最大值
扫描数组从左到右,辅助数组leftMax依次求出记录第i个位置的左侧最大值
扫描数组从右到左,辅助数组rightMax依次求出记录第i个位置的右侧最大值

推荐思路:没听懂
image.png

image.png
初始思路:遍历所有可能
推荐思路:扩充a两倍,搜索a+a串中是否包含b,KMP算法
image.png

扩充题:
有一个数据arr[3,2,7],数组长度表示咖啡机的数量,数组值表示每个咖啡机研磨出一杯咖啡的时间,
有N个人排队用咖啡机,有一台洗咖啡杯的机器,每洗一个咖啡杯用时a,如果咖啡杯不洗自动挥发干净用时b,
求所有人排队喝到咖啡,且最后所有杯子都干净后的总耗时最短的方式

image.png
image.png
image.png
image.png
image.png
玩堆排序必会的数据结构:
image.png
image.png

image.png
image.png
数学题:
三种数:奇数a个,偶数且只有一个2因子b个,偶数且有多个2因子c个
结论,当b=0,c>=a-1,当b!=0,c>=a
image.png

中级提升班6

斐波拉契递推式转通用公式:F(n)=F(n-1)+F(n-2),时间复杂度由O(n)->O(logN)

线性代数:行列式转换
image.png
通过带入F(3),F(2),F(4),F(3)求出a.b.c.d
image.png
得到公式:
image.png
所以问题就变成了求 行列式的n次方问题,利用75中有多少个1即可算出,所以斐波拉契求解时间复杂度就变成了O(logN)
image.png

image.png

image.png
image.png
记规律,题意转化成:N个数中有多少个斐波拉契数
image.png

image.png


image.png
参见 小根堆

github 搜索:algorithmzuo

image.png
推荐思路:dp[i][j]:前i个零食任意装,组成j个体积容量

dp[i][j]= 当第i个零食不装入背包时dp[i-1][j] +当第i个零食装入背包时dp[i-1][j-v[i]]
所以不超过背包容量w的可能装发=dp[i][0]+dp[i][1]+dp[i][2]+dp[i][w]

image.png

image.png
推荐思路:
有序表:
先按工作难度排序,然后同一工作难度的按报酬排序
然后没一组工作难度中最保留报酬最高的一个组长
最后,遍历组长移除组长中难度增加报酬未增加的组长,if job[i+1].hard>job[i+1].hard ,but job[i+1].moneyimage.png

中级提升班7

image.png
初始目录:排序,合并相同前缀,繁琐

推荐思路:建立前缀树,然后深度优先遍历+排序,深度+1则空格+2
image.png

注意数据结构:用树路径存储内容 TreeMap,并且树节点也存储一份PathName
image.png
建前缀树
image.png
深度优先遍历:
image.png

image.png
image.png

image.png
image.png
image.png

image.png

image.png
image.png
贪心算法:
image.png
如果当前i位置是点号,且下个位置i+1是点号,一定在i+1位置放灯
image.png
image.png

子数组的最大累加和,变种:如果有多个累加和最大的子数组,返回“最长”的子数组

image.png

假设法:假设已知这个最大数组,列出其具有的性质
image.png
image.png
image.png

子矩阵最大累加和

image.png
压缩数组:
如求3x4矩阵的最大子矩阵累加和,
等价于=max{matrixSum(0,0), matrixSum(0,1), matrixSum(0,2), matrixSum(1,1), matrixSum(1,2), matrixSum(2,2)}
其中matrixSum(i,j)表示必须同时包含第i~j行的最大子矩阵

如何求matrixSum(i,j),
eg:求matrixSum(0,1)
将第0行(-5,3,6,4)和第1行-(-7,9,-5,3)的数据合并,得到(-12,12,1,7)

所以求matrixSum(0,1)最大矩阵和即(-12,12,1,7)问题变成求单维数组的子数组最大累加和,使用问题6的解法即可

matrixSum(0,0):求第0行的子数组最大累加和
matrixSum(0,1):压缩合并数组第0,1行,求子数组最大累加和
matrixSum(0,2):压缩合并数组第0,2行,求子数组最大累加和
matrixSum(1,1):第1行,求子数组最大累加和
matrixSum(1,2):压缩合并数组第1,2行,求子数组最大累加和
matrixSum(2,2):第2行,求子数组最大累加和

最后结果,即取max{matrixSum(0,0), matrixSum(0,1), matrixSum(0,2), matrixSum(1,1), matrixSum(1,2), matrixSum(2,2)}
image.png

中级提升班8

image.png
image.png
image.png
image.png

image.png
关键点:
1.找到平凡解,归纳递归限制
2.递归改动态规划:进阶版4个小时
image.png

image.png

image.png
注意题意:可以从任意节点开始,但必须是H结束
推荐思路:反向倒推图广度遍历,合并代价表
image.png

image.png

image.png
子序列可以不连续

image.png


最长递增子序列

设dp[i]表示以i结尾的最长递增子序列

dp[i]=for(j: 0~ i-1 ) if(arr[j]<arr[i]) dp[i]=max{ dp[j] } +1

中级提升班9

image.png

子数组最大异或和

暴力思路:枚举所有子数据,求所有子数组的异或值,选出最大

初步优化:利用 arr[i~j]的异或和 = arr[0~i-1]的异或和 ^ arr[0~j]的异或和
先加工出任意arr[0~k]的异或和,然后求出任意 arr[i~j]子数组的最大异或和

高级版的 字典树讲解


image.png
image.png
image.png

image.png
image.png
image.png
image.png
image.png
image.png

image.png
初始思路:滑窗 + hash
推荐思路:动态规划
左神反复强调:看到子串、子数组、子序列的问题,就想每个位置结尾情况下会怎么怎么样,以某个字符结尾会怎么怎么样

以第i位置的结尾的最长无重复子串
= 从 max{ 上次出现元素i的位置,以第i-1位置的结尾的最长无重复子串 左边界 } 到 位置i的字符串

image.png
pre存储的始终是以上一个元素结尾的最长无重复子串的 左边界
image.png
image.png

经典的编辑距离问题:

推荐思路:和最长公共子序列,最长公共子串 是一种解题模型

dp[i][j]表示:str1的前i个字符,变换成str2的前j个字符所需要的代价

注意str1第i个字符是str1[i-1]

image.png

代码超短:填完数组即完成
image.png

image.png
image.png
image.png
image.png
没有讲

中级提升班10

image.png

排序界的天花板

TimSort,和pfdrt