Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions problems/0063.不同路径II.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,39 @@ public:
* 时间复杂度:$O(n × m)$,n、m 分别为obstacleGrid 长度和宽度
* 空间复杂度:$O(n × m)$


同样我们给出空间优化版本:
```CPP
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if (obstacleGrid[0][0] == 1)
return 0;
vector<int> dp(obstacleGrid[0].size());
for (int j = 0; j < dp.size(); ++j)
if (obstacleGrid[0][j] == 1)
dp[j] = 0;
else if (j == 0)
dp[j] = 1;
else
dp[j] = dp[j-1];

for (int i = 1; i < obstacleGrid.size(); ++i)
for (int j = 0; j < dp.size(); ++j){
if (obstacleGrid[i][j] == 1)
dp[j] = 0;
else if (j != 0)
dp[j] = dp[j] + dp[j-1];
}
return dp.back();
}
};
```

* 时间复杂度:$O(n × m)$,n、m 分别为obstacleGrid 长度和宽度
* 空间复杂度:$O(m)$


## 总结

本题是[62.不同路径](https://programmercarl.com/0062.不同路径.html)的障碍版,整体思路大体一致。
Expand Down
8 changes: 6 additions & 2 deletions problems/0236.二叉树的最近公共祖先.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,13 @@

接下来就看如何判断一个节点是节点q和节点p的公共公共祖先呢。

**如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。**
**首先最容易想到的一个情况:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。**

使用后序遍历,回溯的过程,就是从低向上遍历节点,一旦发现如何这个条件的节点,就是最近公共节点了。
**但是很多人容易忽略一个情况,就是节点本身p(q),它拥有一个子孙节点q(p)。**

使用后序遍历,回溯的过程,就是从低向上遍历节点,一旦发现满足第一种情况的节点,就是最近公共节点了。

**但是如果p或者q本身就是最近公共祖先呢?其实只需要找到一个节点是p或者q的时候,直接返回当前节点,无需继续递归子树。如果接下来的遍历中找到了后继节点满足第一种情况则修改返回值为后继节点,否则,继续返回已找到的节点即可。为什么满足第一种情况的节点一定是p或q的后继节点呢?大家可以仔细思考一下。**

递归三部曲:

Expand Down