🤠代码随想录(leetcode)
type
status
date
slug
summary
tags
category
icon
password
📝 力扣
此篇为leetcode算法的基础
方法论: 限时+先写最简单的+调试
包括
1. 一次遍历(学习中)尽可能的理解和记住知识
2. 手撕才是key point
3. 代码随想录
https://www.bilibili.com/video/BV1cy4y167mM/
4. 展开阅读 展开阅读 展开阅读
双向指针
啥时候用: 数组
解法: while(left<right) 什么条件++ — 有些可能需要先排序
两数之和
核心: 递增,只对应唯一的答案,不可以重复使用
三数之和
先排序,然后写出两数之和
记得循环要包多少,push完后还要++
while (nums[left] == nums[left - 1] && right > left)
特例: nums[i]>0 只有相等++之后判断与原值是否一样,以及开头
二分搜索法
核心: 更新左右端点
注意: 坚持对区间的定义才能搞请while(left≤right) right=mid-1
有序数组的平方
核心: 有负数存在,所以最小数一定在中间
注意: 双指针
四数之和
- while(nums[left-1]==nums[left] &&)
- left++; 在搞定后
- if(j>=2 && nums[j-1]==nums[j]&& j != i + 1)
- 越界了 [1000000000,1000000000,1000000000,1000000000]
- 自己强转会比系统强转快
其他
344.反转字符串: 双向指针交换位置
KMP算法
- 字符串匹配的问题 找一模一样的子串
- 最接近的三数之和
- ???
- 统计和小于目标的下标对数目:
- cnt += right - left;
- 有效三角形的个数
- 有三个非负整数,如果小的两个的和大于第三个,那它一定能组成三角形
- 存最多的雨水
- 去掉长边,面积一定变小,尽量在一次循环中处理掉更多的数据
- 接雨水:
- 两个O(n)的做法,两数组: 黑箱子也看成雨水,高度差间有透明玻璃
- 不创建数组的做法: 双指针,利用透明玻璃一定越来越高的原理
同向指针其他
啥时候用: 数组
解法: slow fast
- 子数组子串
- 乘积小于k的子数组(713):
- 无重复字符的最长子串: 滑动窗口最后都是要检测的 hashset 还不如vector{128,0}
- 长度最小的子数组
- 正数性质,滑动窗口到底的for循环
快慢指针
啥时候用: 数组、链表
解法: slow fast
移除元素
核心: 双指针解决,快指针赋值给慢支针跳过元素
注意: erase的时间复杂度是O(n),
中间节点:
核心: 快指针走两步伐,慢走一步
环形节点:
- 快指针走两步,满指针走一步,那么环内,相对速度为+1,则一定会相遇
- while(fast!= nullptr && fast->next!=nullptr)
- if(slow == fast)
环形链表2
- 找入口就是相遇的那点看是 return nullptr;
- 需要注意顺序问题 if(head==slow) 与 head=head->next;
回文链表
- 快慢指针找
- 比较,然后恢复
- 反转链表II
- 反转中间任意一段
- 第一个节点前面加一个哨兵节点
- left right 是
哈希表
栈与队列
啥时候用:
std::stack
的pop()
函数并不返回任何值,它只是从栈中移除栈顶元素栈实现队列: 两个栈
队列实现栈: 一个队列 123 弹出3 则重新把12加到3后面
删除字符串中的所有相邻重复项
string有stack的特性
字符串拼接用加法
逆波兰表达式求值
遇到符号取两个元素,遇到数字放进去
数的后序遍历
stack<int>会比stack<string>好
std::stoi 与 std::to_string
atoi
滑动窗口最大值
优先队列通过大小顶堆实现: 顺序变了,无法pop
单调队列:维护出口值一定是最大的 ,push进来的元素比前面大。则弹出所有前面的元素。 本质上是
递归
验证二叉搜索树
- 区间的思想
- LONG_MIN, LONG_MAX
- 或者用,
- 二叉搜索树——递增序列——做节点的值<节点的树<有节点的值——一定比上个节点值大,判断所有相邻的元素
- 照递归左子树访问节点值,节点值,再递归右子树这样的顺序去遍历 一定是递增序列
- //函数的定义: 节点值是不是比上个节点值大
- 其实就是中序遍历: 递归 处理 递归
遍历 非递归遍历
非递归遍历-中序
层序遍历(广搜优先搜索)
翻转二叉树
对称二叉树
二叉树的最大深度
二叉树的最小深度
完全二叉树节点的数量
平衡二叉树
二叉树的所有路径
左叶子之和
二叉树:14.找左下角的值
二叉树:15. 路径总和
二叉树:16.从中序与后序遍历序列构造二叉树
二叉树:17.最大二叉树
二叉树:18.合并二叉树
二叉树:19.二叉搜索树中的搜索
二叉树:20.验证二叉搜索树
21:56
二叉树:21.二叉搜索树的最小绝对差
11:53
二叉树:22.二叉搜索树中的众数
21:56
二叉树:23. 二叉树的最近公共祖先
19:03
二叉树:24. 二叉搜索树的最近公共祖先
15:34
二叉树:25.二叉搜索树中的插入操作
10:57
二叉树:26.删除二叉搜索树中的节点
26:23
二叉树:27. 修剪二叉搜索树
19:25
二叉树:28.将有序数组转换为二叉搜索树
14:57
二叉树:29.把二叉搜索树转换为累加树
回溯
动态规划
规划基础 背包问题 打家劫舍 股票问题
区间dp 概率dp 不用
dp数组的定义与下标含义 dp如何初始化 遍历顺序 打印dp数组
斐波那契数,。。
输入n,有一个个推,dp[i] 上一个或者两个状态
爬楼梯:
本质是在找规律
使用最小花费爬楼梯:
跳出去了才要加cost
dp[i] = min{dp[i-1] + cost[i-1],dp[i-2] + cost[i-2]}
初始化: dp[0] 与 dp[1]就可以,不需要全部初始化为
不同路径
本质是在找规律: 注意mxn
不同路径 II
初始化不同
整数拆分
dp[i] 对 i 拆分,得到最大的成绩
dp[i] = max(dp[i], j * dp[i-j], j * (i-j))
01背包问题
暴力回溯: 2^n
dp[i][j] 表示背包容量为 j 时,从 0..i 类物品种选取,可以获得的最大价值。
放不放i:
初始化是最难的:
遍历顺序: 都可以,左上方和正上方 dp如果是以为数组则不行
01背包问题: 1维数组版,滚动数组
放不放i:
顺序最难的: 先物品后背包,倒叙遍历:保证每个物品只被加过一次
当前dp[j]要使用上一层左侧的dp值,正序覆盖了上一层左侧的dp值,倒叙避免
分割等和子集
[1, 5, 11, 5]: 价值是5 重量是5
target为22/2: dp[target]== target时候则可以
哪些元素相加等于n/2 即0-1背包,容量为n/2
最后一块石头的重量
分成近似可能相等的两堆
目标和
分成近似可能相等的两堆
打家劫舍
贪心算法
摆动序列
- 首位各算一个摆动 坡度上不加加就好
- 什么时候res加1
- (prediff > 0 && curdiff < 0) || (prediff < 0 && curdiff > 0)
- (prediff == 0 && curdiff < 0) —\
- 初始值
- prediff(前头有一段)=curdiff=0
- result = 1 结尾值
- 遍历到倒数第二个数字
最大子数组的和
- 当前连续和为负数的话,不如从新开始
- if sum<0: sum=0
- 全是负数的时候也很正常
买卖股票最佳时机II
- 收集每天的正利润就好
跳跃游戏
- 最多可以跳几个,但想最后到终点
- 思维不要太局限,i<cov cov的范围也是可以变的
- 只看覆盖范围有无把终点盖住
跳跃游戏II
- 每一步 尽可能提高覆盖范围
- 记录下一步的覆盖范围
K次取反后最大化的数组和
- 一定要用完
- 策略
- 优先对绝对值大的负数优先取反
- 剩下的对绝对值最小的正数,消耗完所有的取反
加油站
- 走一圈回来
- 最关注的是补充消耗后还剩多少油
- 避开消耗太多的,求和一下试试,一旦变负数,就都不行的
- 只能从i+1开始
分发糖果
- 最少的数量,分高则比前面的小孩给的多
柠檬水找零
单调栈
一个栈:保证是递增(后面首个比他大)或者递减(后面首个比他小)
啥时候用:
当前元素 左边 或者 右边 第一个 比他大或者小 的元素
每日温度 O(n^2)
- 存放过遍历过的元素
- 默认赋值为0,那留在栈里面的元素就是全为0
- while (temperatures[i] > temperatures[st.top()] && !st.empty()) 错了,先判空
下一个元素
- 结果打下是数组1大大小
- 单调栈遍历的是数组2
- 默认值-1,找不到更大的元素的话
- 其中
nums1
是nums2
的子集
- 即与上一题的区别在于: 不用记录每一个
下一个更大元素 II
- 可以将[1,2,1] 首位相连 [1,2,1,1,2,1] 但开辟新数组
- 模拟成环的过程中 取余
上一篇
代码整洁之道
下一篇
操作系统基础
Loading...