Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
youngyangyang04 committed Feb 1, 2023
1 parent 653c0a1 commit 7fcbe49
Show file tree
Hide file tree
Showing 18 changed files with 186 additions and 75 deletions.
6 changes: 6 additions & 0 deletions problems/0037.解数独.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
* 你可以假设给定的数独只有唯一解。
* 给定数独永远是 9x9 形式的。

# 算法公开课

**《代码随想录》算法视频公开课:[回溯算法二维递归?解数独不过如此!| LeetCode:37. 解数独](https://www.bilibili.com/video/BV1TW4y1471V/),相信结合视频再看本篇题解,更有助于大家对本题的理解**



## 思路

棋盘搜索问题可以使用回溯法暴力搜索,只不过这次我们要做的是**二维递归**
Expand Down
8 changes: 6 additions & 2 deletions problems/0046.全排列.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@
[3,2,1]
]

## 思路

**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。
# 算法公开课

**《代码随想录》算法视频公开课:[组合与排列的区别,回溯算法求解的时候,有何不同?| LeetCode:46.全排列](https://www.bilibili.com/video/BV19v4y1S79W/),相信结合视频再看本篇题解,更有助于大家对本题的理解**


## 思路


此时我们已经学习了[77.组合问题](https://programmercarl.com/0077.组合.html)[131.分割回文串](https://programmercarl.com/0131.分割回文串.html)[78.子集问题](https://programmercarl.com/0078.子集.html),接下来看一看排列问题。
Expand Down
10 changes: 6 additions & 4 deletions problems/0047.全排列II.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>

# 排列问题(二)

## 47.全排列 II
# 47.全排列 II

[力扣题目链接](https://leetcode.cn/problems/permutations-ii/)

Expand All @@ -27,10 +26,13 @@
* 1 <= nums.length <= 8
* -10 <= nums[i] <= 10

## 思路
**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。
# 算法公开课

**《代码随想录》算法视频公开课:[回溯算法求解全排列,如何去重?| LeetCode:47.全排列 II](https://www.bilibili.com/video/BV1R84y1i7Tm/),相信结合视频再看本篇题解,更有助于大家对本题的理解**


## 思路

这道题目和[46.全排列](https://programmercarl.com/0046.全排列.html)的区别在与**给定一个可包含重复数字的序列**,要返回**所有不重复的全排列**

这里又涉及到去重了。
Expand Down
8 changes: 5 additions & 3 deletions problems/0051.N皇后.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>


# 第51题. N皇后
# 51. N皇后

[力扣题目链接](https://leetcode.cn/problems/n-queens/)

Expand All @@ -28,10 +28,12 @@ n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,
* 输入:n = 1
* 输出:[["Q"]]

## 思路
# 算法公开课

**《代码随想录》算法视频公开课:[这就是传说中的N皇后? 回溯算法安排!| LeetCode:51.N皇后](https://www.bilibili.com/video/BV1Rd4y1c7Bq/),相信结合视频再看本篇题解,更有助于大家对本题的理解**

**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。

## 思路

都知道n皇后问题是回溯算法解决的经典问题,但是用回溯解决多了组合、切割、子集、排列问题之后,遇到这种二维矩阵还会有点不知所措。

Expand Down
5 changes: 4 additions & 1 deletion problems/0062.不同路径.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
* 1 <= m, n <= 100
* 题目数据保证答案小于等于 2 * 10^9

# 算法公开课

**《代码随想录》算法视频公开课:[动态规划中如何初始化很重要!| LeetCode:62.不同路径](https://www.bilibili.com/video/BV1ve4y1x7Eu/),相信结合视频再看本篇题解,更有助于大家对本题的理解**

## 思路

### 深搜
Expand Down Expand Up @@ -237,7 +241,6 @@ public:
然后在给出动规的方法,依然是使用动规五部曲,这次我们就要考虑如何正确的初始化了,初始化和遍历顺序其实也很重要!
就酱,循序渐进学算法,认准「代码随想录」!
## 其他语言版本
Expand Down
5 changes: 4 additions & 1 deletion problems/0063.不同路径II.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
* 1 <= m, n <= 100
* obstacleGrid[i][j] 为 0 或 1

# 算法公开课

**《代码随想录》算法视频公开课:[动态规划,这次遇到障碍了| LeetCode:63. 不同路径 II](https://www.bilibili.com/video/BV1Ld4y1k7c6/),相信结合视频再看本篇题解,更有助于大家对本题的理解**


## 思路

Expand Down Expand Up @@ -200,7 +204,6 @@ public:

也有一些小细节,例如:初始化的部分,很容易忽略了障碍之后应该都是0的情况。

就酱,「代码随想录」值得推荐给身边学算法的同学朋友们,关注后都会发现相见恨晚!


## 其他语言版本
Expand Down
5 changes: 3 additions & 2 deletions problems/0070.爬楼梯.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>

# 70. 爬楼梯

[力扣题目链接](https://leetcode.cn/problems/climbing-stairs/)

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
Expand Down Expand Up @@ -163,7 +164,7 @@ public:

这道题目还可以继续深化,就是一步一个台阶,两个台阶,三个台阶,直到 m个台阶,有多少种方法爬到n阶楼顶。

这又有难度了,这其实是一个完全背包问题,但力扣上没有这种题目,所以后续我在讲解背包问题的时候,今天这道题还会从背包问题的角度上来再讲一遍。
这又有难度了,这其实是一个完全背包问题,但力扣上没有这种题目,所以后续我在讲解背包问题的时候,今天这道题还会从背包问题的角度上来再讲一遍。 如果想提前看一下,可以看这篇:[70.爬楼梯完全背包版本](https://programmercarl.com/0070.%E7%88%AC%E6%A5%BC%E6%A2%AF%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85%E7%89%88%E6%9C%AC.html)

这里我先给出我的实现代码:

Expand All @@ -185,7 +186,7 @@ public:
代码中m表示最多可以爬m个台阶。
**以上代码不能运行哈,我主要是为了体现只要把m换成2,粘过去,就可以AC爬楼梯这道题,不信你就粘一下试试,哈哈**。
**以上代码不能运行哈,我主要是为了体现只要把m换成2,粘过去,就可以AC爬楼梯这道题,不信你就粘一下试试**。
**此时我就发现一个绝佳的大厂面试题**,第一道题就是单纯的爬楼梯,然后看候选人的代码实现,如果把dp[0]的定义成1了,就可以发难了,为什么dp[0]一定要初始化为1,此时可能候选人就要强行给dp[0]应该是1找各种理由。那这就是一个考察点了,对dp[i]的定义理解的不深入。
Expand Down
5 changes: 5 additions & 0 deletions problems/0078.子集.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
  []
]

# 算法公开课

**《代码随想录》算法视频公开课:[回溯算法解决子集问题,树上节点都是目标集和! | LeetCode:78.子集](https://www.bilibili.com/video/BV1U84y1q7Ci),相信结合视频再看本篇题解,更有助于大家对本题的理解**


# 思路

求子集问题和[77.组合](https://programmercarl.com/0077.组合.html)[131.分割回文串](https://programmercarl.com/0131.分割回文串.html)又不一样了。
Expand Down
7 changes: 5 additions & 2 deletions problems/0090.子集II.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>

# 子集问题(二)

## 90.子集II
# 90.子集II

[力扣题目链接](https://leetcode.cn/problems/subsets-ii/)

Expand All @@ -26,6 +25,10 @@
[]
]

# 算法公开课

**《代码随想录》算法视频公开课:[回溯算法解决子集问题,如何去重?| LeetCode:90.子集II](https://www.bilibili.com/video/BV1vm4y1F71J/),相信结合视频再看本篇题解,更有助于大家对本题的理解**


## 思路

Expand Down
5 changes: 5 additions & 0 deletions problems/0093.复原IP地址.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
* s 仅由数字组成


# 算法公开课

**《代码随想录》算法视频公开课:[回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址](https://www.bilibili.com/video/BV1XP4y1U73i/),相信结合视频再看本篇题解,更有助于大家对本题的理解**


# 思路

做这道题目之前,最好先把[131.分割回文串](https://programmercarl.com/0131.分割回文串.html)这个做了。
Expand Down
5 changes: 5 additions & 0 deletions problems/0096.不同的二叉搜索树.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

![](https://img-blog.csdnimg.cn/20210113161941835.png)

# 算法公开课

**《代码随想录》算法视频公开课:[动态规划找到子状态之间的关系很重要!| LeetCode:96.不同的二叉搜索树](https://www.bilibili.com/video/BV1eK411o7QA/),相信结合视频再看本篇题解,更有助于大家对本题的理解**


## 思路

这道题目描述很简短,但估计大部分同学看完都是懵懵的状态,这得怎么统计呢?
Expand Down
30 changes: 19 additions & 11 deletions problems/0134.加油站.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

## 暴力方法

暴力的方法很明显就是$O(n^2)$的,遍历每一个加油站为起点的情况,模拟一圈。
暴力的方法很明显就是O(n^2)的,遍历每一个加油站为起点的情况,模拟一圈。

如果跑了一圈,中途没有断油,而且最后油量大于等于0,说明这个起点是ok的。

Expand Down Expand Up @@ -119,8 +119,8 @@ public:
}
};
```
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$
* 时间复杂度:O(n)
* 空间复杂度:O(1)

**其实我不认为这种方式是贪心算法,因为没有找出局部最优,而是直接从全局最优的角度上思考问题**

Expand All @@ -136,18 +136,26 @@ public:

每个加油站的剩余量rest[i]为gas[i] - cost[i]

i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,起始位置从i+1算起,再从0计算curSum。
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。

如图:
![134.加油站](https://img-blog.csdnimg.cn/20201213162821958.png)

那么为什么一旦[i,j] 区间和为负数,起始位置就可以是j+1呢,j+1后面就不会出现更大的负数?
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230117165628.png)

那么为什么一旦[0,i] 区间和为负数,起始位置就可以是i+1呢,i+1后面就不会出现更大的负数?

如果出现更大的负数,就是更新i,那么起始位置又变成新的i+1了。

那有没有可能 [0,i] 区间 选某一个作为起点,累加到 i这里 curSum是不会小于零呢? 如图:

如果出现更大的负数,就是更新j,那么起始位置又变成新的j+1了。
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230117170703.png)

而且j之前出现了多少负数,j后面就会出现多少正数,因为耗油总和是大于零的(前提我们已经确定了一定可以跑完全程)。
如果 curSum<0 说明 区间和1 + 区间和2 < 0, 那么 假设从上图中的位置开始计数curSum不会小于0的话,就是 区间和2>0。

**那么局部最优:当前累加rest[j]的和curSum一旦小于0,起始位置至少要是j+1,因为从j开始一定不行。全局最优:找到可以跑一圈的起始位置**
区间和1 + 区间和2 < 0 同时 区间和2>0,只能说明区间和1 < 0, 那么就会从假设的箭头初就开始从新选择其实位置了。


**那么局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。全局最优:找到可以跑一圈的起始位置**

局部最优可以推出全局最优,找不出反例,试试贪心!

Expand All @@ -173,8 +181,8 @@ public:
}
};
```
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$
* 时间复杂度:O(n)
* 空间复杂度:O(1)
**说这种解法为贪心算法,才是有理有据的,因为全局最优解是根据局部最优推导出来的**。
Expand Down
6 changes: 6 additions & 0 deletions problems/0343.整数拆分.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
* 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
* 说明: 你可以假设 n 不小于 2 且不大于 58。


# 算法公开课

**《代码随想录》算法视频公开课:[动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分](https://www.bilibili.com/video/BV1Mg411q7YJ/),相信结合视频再看本篇题解,更有助于大家对本题的理解**


## 思路

看到这道题目,都会想拆成两个呢,还是三个呢,还是四个....
Expand Down
3 changes: 1 addition & 2 deletions problems/0406.根据身高重建队列.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,8 @@ public:

对于写题解的同学,刷题用什么语言影响就非常大,如果自己语言没有学好而强调算法和编程语言没关系,其实是会误伤别人的。

**这也是我为什么统一使用C++写题解的原因**,其实用其他语言java、python、php、go啥的,我也能写,我的Github上也有用这些语言写的小项目,但写题解的话,我就不能保证把语言特性这块讲清楚,所以我始终坚持使用最熟悉的C++写题解。
**这也是我为什么统一使用C++写题解的原因**

**而且我在写题解的时候涉及语言特性,一般都会后面加上括号说明一下。没办法,认真负责就是我,哈哈**

## 其他语言版本

Expand Down
34 changes: 33 additions & 1 deletion problems/0417.太平洋大西洋水流问题.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,42 @@
<img src="../pics/训练营.png" width="1000"/>
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>



# 417. 太平洋大西洋水流问题

[题目链接](https://leetcode.cn/problems/pacific-atlantic-water-flow/)

有一个 m × n 的矩形岛屿,与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。

这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights , heights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度 。

岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。

返回网格坐标 result 的 2D 列表 ,其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动 既可流向太平洋也可流向大西洋 。

示例 1:

![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230129103212.png)

* 输入: heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
* 输出: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]

示例 2:

* 输入: heights = [[2,1],[1,2]]
* 输出: [[0,0],[0,1],[1,0],[1,1]]

提示:

* m == heights.length
* n == heights[r].length
* 1 <= m, n <= 200
* 0 <= heights[r][c] <= 10^5



## 思路

不少同学可能被这道题的题目描述迷惑了,其实就是找到哪些点 可以同时到达太平洋和大西洋。 流动的方式只能从高往低流。
Expand Down Expand Up @@ -96,7 +128,7 @@ public:
## 优化
那么我们可以 反过来想,从太平洋边上的节点 逆流而上,将遍历过的节点都标记上。 从大西洋的边上节点 逆流而长,讲遍历过的节点也标记上。
那么我们可以 反过来想,从太平洋边上的节点 逆流而上,将遍历过的节点都标记上。 从大西洋的边上节点 逆流而长,将遍历过的节点也标记上。 然后两方都标记过的节点就是既可以流太平洋也可以流大西洋的节点。
从太平洋边上节点出发,如图:
Expand Down
Loading

0 comments on commit 7fcbe49

Please sign in to comment.