LeetCode-32
1185. 一周中的第几天
Tomohiko Sakamoto
算法- 虽然是简单题也有很多知识点呢
- 解释
1 | class Solution { |
2583. 二叉树中的第 K 大层和
1 | class Solution { |
- 用ranges获取第k大的数
1 | class Solution { |
LCP 30. 魔塔游戏
- 当遇到HP不够的时候,考虑贪心,依次将已经遇到过的房间中最小的房间向后移动
- 移动后放入delay中,最后加上delay看HP够不够就好了
1 | class Solution { |
1696. 跳跃游戏 VI
- 看提示就会了
1 | class Solution { |
292. Nim 游戏
- 用dp[i]表示i个石头是否存在必胜策略,已知i = 1, 2, 3时,一定有必胜策略
- 那么对于4,无论我拿多少,对手都有必胜策略,那么我必输
- 对于5,6,7,我分别拿1,2,3就会得到4,对手陷入必输,那么我必胜
- 也就是前三个数全true,我就是false,前三个数有false,我就是true
- 可以证明,4的倍数一定输
- 连续三个true后必跟一个false
- 每个false后面一定有3个true
1 | class Solution { |
2476. 二叉搜索树最近节点查询
中序+二分
1 | class Solution { |
235. 二叉搜索树的最近公共祖先
- 这道题与236. 二叉树的最近公共祖先不同,这道题是在二叉搜索树上寻找
- 对于根节点,如果两个数分别大于等于和小于等于这个节点,说明当前根节点就是公共祖先
- 如果都大于或小于当前根节点,说明要向左子树或右子树移动,继续寻找
1 | class Solution { |
938. 二叉搜索树的范围和
- 如果当前节点大于high,则不考虑右子树和当前节点,直接转移到左子树,小于low同理
- 如果当前节点在high和low之间,则返回当前节点值加上左右两棵子树的和
1 | class Solution { |
2867. 统计树中的合法路径数目
思路
- 首先题目说是树,所以要考虑最广泛的n叉树的情况
- 涉及到素数,所以可以先素数筛把需要用到的素数缓存起来
- 最笨的方法是,依次从所有素数出发,dfs直到遇到下一个素数或者遇到没有未访问节点位置,统计总共的路线数
- 一个素数的所有孩子可以看成一个子树,到达每个节点的路径数就是节点数
- 总路线数就是
- N个子树按照上面的要求dfs时所遇到的节点数之和()
- 考虑到dfs过程中遇到的都是非素数,那么任意两个子树之间的任意两点之间的路径也是题目所求路径,总数为N个子树节点数两两相乘再相加()
- 为了减少重复的统计,使用并查集,将素数节点去除得到X个子树,计算X个子树的节点个数
- 根据公式,可以将二重循环简化为一重循环
代码
1 | class Solution { |
2673. 使二叉树所有路径值相等的最小代价
思路
- 计算每个节点从根到当前节点的路径和
- 计算每个节点的子路径的最大值
- 对每个节点,计算两个子节点的子路径最大值之差,给较小的节点增加这个差值
代码
1 | class Solution { |
- 去掉不必要的判断
1 | inline int leftChildOf(int node) { return ((node + 1) << 1) - 1; } |
一行流
1 | inline int leftChildOf(int node) { return ((node + 1) << 1) - 1; } inline int rightChildOf(int node) { return ((node + 1) << 1); } inline int parentOf(int node) { return ((node + 1) >> 1) - 1; } class Solution { int solve(int n, int node, vector<int>& childMax) { return childMax[parentOf(node)] - childMax[node] + (leftChildOf(node) < n ? solve(n, leftChildOf(node), childMax) + solve(n, rightChildOf(node), childMax) : 0);} public: int minIncrements(int n, vector<int>& cost) { vector<int> pathSum(n), childMax(n); pathSum[0] = cost[0]; for(int i = 1; i < n; i++) pathSum[i] = cost[i] + pathSum[parentOf(i)]; for(int i = n-1; i >= n/2; i--) childMax[i] = pathSum[i]; for(int i = n/2 - 1; i >= 0; i--) childMax[i] = max(childMax[leftChildOf(i)], childMax[rightChildOf(i)]); return solve(n, 1, childMax) + solve(n, 2, childMax); }}; |
2487. 从链表中移除节点
单调栈
1 | class Solution { |
不用stack
1 | class Solution { |
2397. 被列覆盖的最多行数
状态压缩
1 | class Solution { |
全排列
1 | class Solution { |
2581. 统计可能的树根数目
- 看题解的思路
- 树形dp
1 | class Solution { |
1944. 队列中可以看到的人数
- 还好,就是单调栈的简单应用
1 | class Solution { |
2807. 在链表中插入最大公约数
1 | class Solution { |
383. 赎金信
1 | class Solution { |
447. 回旋镖的数量
1 | class Solution { |
2707. 字符串中的额外字符
- 很常规的dp
1 | class Solution { |
2696. 删除子串后的字符串最小长度
- 括号匹配的思路
1 | class Solution { |
2645. 构造有效字符串的最少插入数
1 | class Solution { |
2085. 统计出现过一次的公共字符串
1 | class Solution { |
2182. 构造限制重复的字符串
1 | class Solution { |
83. 删除排序链表中的重复元素
1 | class Solution { |
82. 删除排序链表中的重复元素 II
1 | class Solution { |
2368. 受限条件下可到达节点的数目
dfs
- 我的评价是,平平无奇
1 | class Solution { |
非递归dfs
1 | class Solution { |
并查集
1 | class Solution { |
238. 除自身以外数组的乘积
- 虽然但是,空间
O(1)
不是应该原地修改吗?
1 | class Solution { |
225. 用队列实现栈
1 | class MyStack { |