Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
youngyangyang04 committed Nov 4, 2022
1 parent 6731e45 commit f29352f
Show file tree
Hide file tree
Showing 16 changed files with 114 additions and 117 deletions.
22 changes: 12 additions & 10 deletions problems/0037.解数独.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

[N皇后问题](https://programmercarl.com/0051.N皇后.html)是因为每一行每一列只放一个皇后,只需要一层for循环遍历一行,递归来来遍历列,然后一行一列确定皇后的唯一位置。

本题就不一样了,**本题中棋盘的每一个位置都要放一个数字,并检查数字是否合法,解数独的树形结构要比N皇后更宽更深**
本题就不一样了,**本题中棋盘的每一个位置都要放一个数字(而N换后是一行只放一个皇后),并检查数字是否合法,解数独的树形结构要比N皇后更宽更深**

因为这个树形结构太大了,我抽取一部分,如图所示:

Expand All @@ -57,7 +57,7 @@

**递归函数的返回值需要是bool类型,为什么呢?**

因为解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,相当于找从根节点到叶子节点一条唯一路径,所以需要使用bool返回值,这一点在[回溯算法:N皇后问题](https://programmercarl.com/0051.N皇后.html)中已经介绍过了,一样的道理
因为解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,相当于找从根节点到叶子节点一条唯一路径,所以需要使用bool返回值。

代码如下:

Expand Down Expand Up @@ -157,15 +157,16 @@ private:
bool backtracking(vector<vector<char>>& board) {
for (int i = 0; i < board.size(); i++) { // 遍历行
for (int j = 0; j < board[0].size(); j++) { // 遍历列
if (board[i][j] != '.') continue;
for (char k = '1'; k <= '9'; k++) { // (i, j) 这个位置放k是否合适
if (isValid(i, j, k, board)) {
board[i][j] = k; // 放置k
if (backtracking(board)) return true; // 如果找到合适一组立刻返回
board[i][j] = '.'; // 回溯,撤销k
if (board[i][j] == '.') {
for (char k = '1'; k <= '9'; k++) { // (i, j) 这个位置放k是否合适
if (isValid(i, j, k, board)) {
board[i][j] = k; // 放置k
if (backtracking(board)) return true; // 如果找到合适一组立刻返回
board[i][j] = '.'; // 回溯,撤销k
}
}
}
return false; // 9个数都试完了,都不行,那么就返回false
return false; // 9个数都试完了,都不行,那么就返回false
}
}
}
return true; // 遍历完没有返回false,说明找到了合适棋盘位置了
Expand Down Expand Up @@ -197,6 +198,7 @@ public:
backtracking(board);
}
};
```

## 总结
Expand Down
8 changes: 8 additions & 0 deletions problems/0040.组合总和II.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,16 @@ if (sum == target) {
* used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
* used[i - 1] == false,说明同一树层candidates[i - 1]使用过

可能有的录友想,为什么 used[i - 1] == false 就是同一树层呢,因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。

而 used[i - 1] == true,说明是进入下一层递归,去下一个数,所以是树枝上,如图所示:

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


**这块去重的逻辑很抽象,网上搜的题解基本没有能讲清楚的,如果大家之前思考过这个问题或者刷过这道题目,看到这里一定会感觉通透了很多!**


那么单层搜索的逻辑代码如下:

```CPP
Expand Down
2 changes: 1 addition & 1 deletion problems/0047.全排列II.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private:
}
for (int i = 0; i < nums.size(); i++) {
// used[i - 1] == true,说明同一树枝nums[i - 1]使用过
// used[i - 1] == false,说明同一树层nums[i - 1]使用过
// used[i - 1] == false,说明同一树层nums[i - 1]使用过
// 如果同一树层nums[i - 1]使用过则直接跳过
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
Expand Down
2 changes: 1 addition & 1 deletion problems/0062.不同路径.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ for (int j = 0; j < n; j++) dp[0][j] = 1;
4. 确定遍历顺序
这里要看一下递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。
这里要看一下递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。
这样就可以保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。
Expand Down
4 changes: 4 additions & 0 deletions problems/0070.爬楼梯.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
* 1 阶 + 2 阶
* 2 阶 + 1 阶

# 视频讲解

**《代码随想录》算法视频公开课:[带你学透动态规划-爬楼梯|LeetCode:70.爬楼梯)](https://www.bilibili.com/video/BV17h411h7UH),相信结合视频在看本篇题解,更有助于大家对本题的理解**


## 思路

Expand Down
11 changes: 5 additions & 6 deletions problems/0070.爬楼梯完全背包版本.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
<img src="../pics/训练营.png" width="1000"/>
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 动态规划:以前我没得选,现在我选择再爬一次!

之前讲这道题目的时候,因为还没有讲背包问题,所以就只是讲了一下爬楼梯最直接的动规方法(斐波那契)。

**这次终于讲到了背包问题,我选择带录友们再爬一次楼梯!**

## 70. 爬楼梯
# 70. 爬楼梯

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

Expand All @@ -36,6 +31,10 @@

## 思路

之前讲这道题目的时候,因为还没有讲背包问题,所以就只是讲了一下爬楼梯最直接的动规方法(斐波那契)。

**这次终于讲到了背包问题,我选择带录友们再爬一次楼梯!**

这道题目 我们在[动态规划:爬楼梯](https://programmercarl.com/0070.爬楼梯.html) 中已经讲过一次了,原题其实是一道简单动规的题目。

既然这么简单为什么还要讲呢,其实本题稍加改动就是一道面试好题。
Expand Down
2 changes: 1 addition & 1 deletion problems/0101.对称二叉树.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ class Solution:
st.append(root.left)
st.append(root.right)
while st:
leftNode = st.pop()
rightNode = st.pop()
leftNode = st.pop()
if not leftNode and not rightNode:
continue
if not leftNode or not rightNode or leftNode.val != rightNode.val:
Expand Down
20 changes: 0 additions & 20 deletions problems/0102.二叉树的层序遍历.md
Original file line number Diff line number Diff line change
Expand Up @@ -2073,26 +2073,6 @@ class Solution:
if curnode.right: queue.append(curnode.right)
return root

# 链表解法
class Solution:
def connect(self, root: 'Node') -> 'Node':
if not root:
return None
first = root
while first: # 遍历每一层
dummyHead = Node(None) # 为下一行创建一个虚拟头节点,相当于下一行所有节点链表的头结点(每一层都会创建);
tail = dummyHead # 为下一行维护一个尾节点指针(初始化是虚拟节点)
cur = first
while cur: # 遍历当前层的节点
if cur.left: # 链接下一行的节点
tail.next = cur.left
tail = tail.next
if cur.right:
tail.next = cur.right
tail = tail.next
cur = cur.next # cur同层移动到下一节点
first = dummyHead.next # 此处为换行操作,更新到下一行
return root
```
JavaScript:
```javascript
Expand Down
4 changes: 0 additions & 4 deletions problems/0150.逆波兰表达式求值.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,8 @@ C++代码如下:
class Solution {
public:
int evalRPN(vector<string>& tokens) {
<<<<<<< HEAD
stack<long long> st;
=======
// 力扣修改了后台测试数据,需要用longlong
stack<long long> st;
>>>>>>> 28f3b52a82e3cc650290fb02030a53900e122f43
for (int i = 0; i < tokens.size(); i++) {
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
long long num1 = st.top();
Expand Down
2 changes: 1 addition & 1 deletion problems/0242.有效的字母异位词.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ C#:

## 相关题目

* 383.赎金信
* [383.赎金信](https://programmercarl.com/0383.%E8%B5%8E%E9%87%91%E4%BF%A1.html)
* 49.字母异位词分组
* 438.找到字符串中所有字母异位词

Expand Down
4 changes: 2 additions & 2 deletions problems/0279.完全平方数.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<img src="../pics/训练营.png" width="1000"/>
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 动态规划:一样的套路,再求一次完全平方数

## 279.完全平方数

# 279.完全平方数

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

Expand Down
3 changes: 1 addition & 2 deletions problems/0322.零钱兑换.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
<img src="../pics/训练营.png" width="1000"/>
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 动态规划: 给我个机会,我再兑换一次零钱

## 322. 零钱兑换
# 322. 零钱兑换

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

Expand Down
3 changes: 3 additions & 0 deletions problems/0509.斐波那契数.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ F(n) = F(n - 1) + F(n - 2),其中 n > 1

* 0 <= n <= 30

# 视频讲解

**《代码随想录》算法视频公开课:[手把手带你入门动态规划 | leetcode:509.斐波那契数](https://www.bilibili.com/video/BV1f5411K7mo),相信结合视频在看本篇题解,更有助于大家对本题的理解**

## 思路

Expand Down
Loading

0 comments on commit f29352f

Please sign in to comment.