刷题记录- 202512
已做题目
sorting
quick sort/ quick selection
思路: divide and conquer. 每次找到start, end-1 范围内array[end]适合插入的位置,该位置左边是大于array[end]的所以元素, 右边是所有小于array[end]的元素
searching
思路: 旋转数组考虑2点: arr[left]和arr[right]大小关系 和arr[mid]与arr[left]之间关系,怎么在非递增矩阵情况下right边界一直默认左移且默认在最小的结果位置上而不会死循环。
思路:移动边界时,+1, -1是为了避免死循环,不+/-1是为了保留数值
LinkedList
思路: fast slow pointer, 对 slow.next节点开始, fast 节点结尾的group进行反转
heap/Array/Stack
思路: min-heap, 时间复杂度nlogk
滑动窗口+ 单调队列(单调递减队列存放window里第1,2,3.。k大值)
思路: 单调栈 存储, left[i] = 从左往右数比heights[i] 小的最大数 right[i]同理
Set
思路: sliding window + set
DFS
permutation 排列
思路: dfs + 排序去重逻辑
要先把选项排序,然后在dfs的递归里的for循环中对比 opt[i-1], opt[i]把已经选择过的元素skip掉
combination
思路: 类似凑硬币问题,有2个问题先要解决
选项数字可能重复,需要先通过字典进行去重和次数存储
dfs recursion里面的for循环 是当前选项数字的使用次数。(排序问题里面的for循环是当前位置选择用哪个数字)
terminal state 递归层数最大是去重后的选项数 或者 和为target的组合数字的层数。有2个条件。
思路:组合问题,不是排列问题, recursion 里只有2个child/ 选和不选。 重点是终止条件的先后
备注: 细节问题, 注意传参被传错
Palidrome回文数
思路: 分割回文数得到所有回文数组合, 和 全排列逻辑类似, 区别只在
for循环里面从选择数字变成 选择 边界数字(分割的最后一个数字)
for循环里面,进入下一层递归时,从起始位置pos +1变成终止位置i+1 来跳过中间的分割选项
加入dp存储 回文数状态,dp[i][j] 取决于dp[i+1][j-1] 和s[i]==s[j]
回文数判断方法:
分奇数偶数长度情况判断corner case, 然后从外到内或内到外延申判断
BFS
思路: bfs, 遍历整个matrix, 每次找到element=1 就bfs queue。 注意:queue append要是当前位置的上下左右4个方向,而不是右下,因为queue append的方向并不是往右下角遍历
Tree
树遍历
思路: 前缀和 + 树遍历, 可以参考和为target的子数组题目,只是变成树结构遍历而已
注意:o1, o2不能是ancester
代码
recursion swap 左右节点即可
DP
dp思路技巧回顾
问题凡是带 "最xx" 最长最短等等 找某个状态的极端值,用dp存储状态 + 贪心算法找极值
dp存储的状态1个维度是存答案的状态,其他维度是其他中间状态。
比如 ”最长长度“,dp[i][j] 里i存长度, j可以存其他维度状态
思路:二维dp, dp[i][d], i是以第i个数字结尾的等差=d的子序列长度
思路: 二维dp,dp[i][j] , i, j都是代表字符的位置
思路: dp[i] = 以s[i]结尾的字串的最长递增子序列长度
思路:
拆分2个问题
子串变成回文数的编辑次数 cost[i][j]
对字串s[:i] 分割为 j 次的最小次数 dp[i][j]
dp[i][j]转移方程: dp[i][j] 变成用 i1 遍历0 ~i 位置里的 上一个位置状态dp[i1][j-1] + 最后一次编辑的次数cost[i1][i-1]
code
思路: 找最长回文数, 中心延展法 内到外延申
备注: 如果是检测是否回文数, 可以由外到内递归判断 dp[i:j] = dp[ i+1:j-1 ] && s[i]==s[j]
待做题目
sorting
quick sort
merge sort
heap sort
Searching
Array
DFS
BFS
DP
Tree
树遍历
Graph
Last updated
Was this helpful?