This commit is contained in:
youngyangyang04
2020-10-13 09:19:14 +08:00
parent 1e0c5e671b
commit f913dc3868
4 changed files with 86 additions and 58 deletions

View File

@ -309,6 +309,7 @@
|[0501.二叉搜索树中的众数](https://github.com/youngyangyang04/leetcode/blob/master/problems/0501.二叉搜索树中的众数.md) |二叉树 |简单|**递归/中序遍历**|
|[0513.找树左下角的值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0513.找树左下角的值.md) |二叉树 |中等|**递归** **迭代**|
|[0515.在每个树行中找最大值](https://github.com/youngyangyang04/leetcode/blob/master/problems/0515.在每个树行中找最大值.md) |二叉树 |简单|**广度优先搜索/队列**|
|[0530.二叉搜索树的最小绝对差](https://github.com/youngyangyang04/leetcode/blob/master/problems/0530.二叉搜索树的最小绝对差.md) |二叉树搜索树 |简单|**递归** **迭代**|
|[0538.把二叉搜索树转换为累加树](https://github.com/youngyangyang04/leetcode/blob/master/problems/0538.把二叉搜索树转换为累加树.md) |二叉树 |简单|**递归** **迭代**|
|[0541.反转字符串II](https://github.com/youngyangyang04/leetcode/blob/master/problems/0541.反转字符串II.md) |字符串 |简单| **模拟**|
|[0559.N叉树的最大深度](https://github.com/youngyangyang04/leetcode/blob/master/problems/0559.N叉树的最大深度.md) |N叉树 |简单| **递归**|
@ -336,7 +337,7 @@
# 关于作者
大家好我是程序员CarlACM 校赛、黑龙江省赛、东北四省赛金牌,和亚洲区域赛铜牌获得者,哈工大计算机硕士毕业,先后在腾讯和百度从事后端技术研发CSDN博客专家。对算法和C++后端技术有一定的见解利用工作之余重新刷leetcode。
大家好我是程序员Carl哈工大师兄,ACM 校赛、黑龙江省赛、东北四省赛金牌亚洲区域赛铜牌获得者先后在腾讯和百度从事后端技术研发CSDN博客专家。对算法和C++后端技术有一定的见解利用工作之余重新刷leetcode。
**加我的微信,备注:「个人简单介绍」+「组队刷题」** 拉你进刷题群,每天一道经典题目分析,而且题目不是孤立的,每一道题目之间都是有关系的,都是由浅入深一脉相承的,所以学习效果最好是每篇连续着看,也许之前你会某些知识点,但是一直没有把知识点串起来,这里每天一篇文章就会帮你把知识点串起来。我也花了不少精力来整理我的题解,**而且我不会在群里发任何广告,纯自己学习和分享。 欢迎你的加入!**

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -36,22 +36,29 @@ KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部
本篇将以如下顺序来讲解KMP
1. 什么是KMP
2. KMP可以解决什么问题
3. 分析KMP算法里的next数组
4. 什么是前缀表
5. 再分析为什么要是前缀表而不是什么哈希表其他表等等,偏偏要是前缀表。
6. 一步一步推导前缀表是怎么求的
7. 时间复杂度分析
8. 前缀表与next数组的关系
9. 如何使用next数组来做一遍匹配的过程
10. 构造next数组
11. 使用next数组进行匹配
12. 前缀表统一减一右移的KMP实现方式
13. 前缀表不减一的KMP实现方式
14. 总结
可以说步步相扣,大家要跟紧,哈哈。
* 什么是KMP
* KMP有什么用
* 什么是前缀表
* 为什么一定要用前缀表
* 如何计算前缀表
* 前缀表与next数组
* 使用next数组来匹配
* 时间复杂度分析
* 构造next数组
* 使用next数组来做匹配
* 前缀表统一减一 C++代码实现
* 前缀表不减一C++实现
* 总结
读完本篇可以顺便把leetcode上28.实现strStr()题目做了。
如果文字实在看不下去就看我在B站上的视频吧如下
* [帮你把KMP算法学个通透理论篇B站](https://www.bilibili.com/video/BV1PD4y1o7nd/)
* [帮你把KMP算法学个通透求next数组代码篇B站](https://www.bilibili.com/video/BV1M5411j7Xx/)
# 什么是KMP
@ -525,5 +532,7 @@ public:
可以说把KMP的每一个细微的细节都扣了出来毫无遮掩的展示给大家了
> 更多算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。

View File

@ -1,17 +1,35 @@
## 题目地址
https://leetcode-cn.com/problems/search-in-a-binary-search-tree/
## 思路
> 二叉搜索树登场!
### 递归法
# 700.二叉搜索树中的搜索
先来看递归的实现方式
给定二叉搜索树BST的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL
依然从递归三要素开始分析:
例如,
* 确定递归函数的参数和返回值
* 确定终止条件
* 确定单层递归的逻辑
<img src='../pics/700.二叉搜索树中的搜索.png' width=600> </img></div>
在上述示例中,如果要找的值是 5但因为没有节点值为 5我们应该返回 NULL。
# 思路
之前我们讲了都是普通二叉树,那么接下来看看二叉搜索树。
在[关于二叉树,你该了解这些!](https://mp.weixin.qq.com/s/_ymfWYvTNd2GvWvC5HOE4A)中,我们已经讲过了二叉搜索树。
二叉搜索树是一个有序树:
* 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
* 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
* 它的左、右子树也分别为二叉搜索树
这就决定了,二叉搜索树,递归遍历和迭代遍历和普通二叉树都不一样。
本题,其实就是在二叉搜索树中搜索一个节点。那么我们来看看应该如何遍历。
## 递归法
1. 确定递归函数的参数和返回值
@ -33,17 +51,25 @@ if (root == NULL || root->val == val) return root;
3. 确定单层递归的逻辑
来看一下二叉搜索树的单层递归逻辑有何不同 因为二叉搜索树的节点是有序的所以可以有方向的去搜索如果root->val > val搜索左子树如果root->val < val就搜索右子树最后如果都没有搜索到就返回NULL
看看二叉搜索树的单层递归逻辑有何不同
因为二叉搜索树的节点是有序的,所以可以有方向的去搜索。
如果root->val > val搜索左子树如果root->val < val就搜索右子树最后如果都没有搜索到就返回NULL
代码如下
```
if (root->val > val) return searchBST(root->left, val);
if (root->val > val) return searchBST(root->left, val); // 注意这里加了return
if (root->val < val) return searchBST(root->right, val);
return NULL;
```
这里可能会疑惑在递归遍历的时候什么时候直接return 递归函数的返回值什么时候不用加这个 return 这取决于对递归函数的定义这里定义的递归函数就是返回 要查找的元素所在的节点而这个节点就是我们所求所以直接return递归函数的返回值
这里可能会疑惑在递归遍历的时候什么时候直接return 递归函数的返回值什么时候不用加这个 return
我们在[二叉树:递归函数究竟什么时候需要返回值,什么时候不要返回值?](https://mp.weixin.qq.com/s/6TWAVjxQ34kVqROWgcRFOg)中讲了如果要搜索一条边递归函数就要加返回值这里也是一样的道理
**因为搜索到目标节点了就要立即return了这样才是找到节点就返回搜索某一条边如果不加return就是遍历整棵树了。**
整体代码如下
@ -56,16 +82,23 @@ TreeNode* searchBST(TreeNode* root, int val) {
}
```
### 迭代法
## 迭代法
一提到二叉树遍历的迭代法可能立刻想起使用栈来模拟深度遍历使用队列来模拟广度遍历其实因为二叉搜索树的特殊性也就是节点的有序性可以不使用辅助栈或者队列就可以写出迭代法
一提到二叉树遍历的迭代法可能立刻想起使用栈来模拟深度遍历使用队列来模拟广度遍历
对于一般二叉树模拟递归的过程中还有一个回溯的过程例如走一个左方向的分支走到头了那么要调头在走右分支而对于二叉搜索树不需要回溯的过程因为节点的有序性就帮我们确定了搜索的方向
对于二叉搜索树可就不一样了因为二叉搜索树的特殊性也就是节点的有序性可以不使用辅助栈或者队列就可以写出迭代法
对于一般二叉树递归过程中还有回溯的过程例如走一个左方向的分支走到头了那么要调头在走右分支
**对于二叉搜索树不需要回溯的过程因为节点的有序性就帮我们确定了搜索的方向。**
例如要搜索元素为3的节点**我们不需要搜索其他节点也不需要做回溯查找的路径已经规划好了。**
中间节点如果大于3就向左走如果小于3就向右走如图
看如下图中的这颗二叉搜索树例如要搜索元素为3的节点我们不需要搜索其他节点也不需要做回溯查找的路径已经规划好了
![二叉搜索树](https://img-blog.csdnimg.cn/20200812190213280.png)
迭代法代码如下
所以迭代法代码如下
```
class Solution {
@ -81,34 +114,19 @@ public:
};
```
## C++代码
第一次看到了如此简单的迭代法是不是感动的痛哭流涕哭一会~
### 递归
```
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if (root == NULL || root->val == val) return root;
if (root->val > val) return searchBST(root->left, val);
if (root->val < val) return searchBST(root->right, val);
return NULL;
}
};
```
# 总结
本篇我们介绍了二叉搜索树的遍历方式因为二叉搜索树的有序性遍历的时候要比普通二叉树简单很多
但是一些同学很容易忽略二叉搜索树的特性所以写出遍历的代码就未必真的简单了
所以针对二叉搜索树的题目一样要利用其特性
文中我依然给出递归和迭代两种方式可以看出写法都非常简单就是利用了二叉搜索树有序的特点
就酱如果学到了就转发给身边需要的同学吧
### 迭代
```
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
while (root != NULL) {
if (root->val > val) root = root->left;
else if (root->val < val) root = root->right;
else return root;
}
return NULL;
}
};
```
> 更多算法干货文章持续更新可以微信搜索「代码随想录」第一时间围观关注后回复「Java」「C++」 「python」「简历模板」「数据结构与算法」等等就可以获得我多年整理的学习资料。