Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
Ainevsia committed Aug 2, 2023
1 parent d65c487 commit 30e1344
Show file tree
Hide file tree
Showing 9 changed files with 319 additions and 1 deletion.
10 changes: 9 additions & 1 deletion notes/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,12 @@
- [654. 最大二叉树](./day20/lc654.md)
- [617. 合并二叉树](./day20/lc617.md)
- [700.二叉搜索树中的搜索](./day20/lc700.md)
- [98. 验证二叉搜索树](./day20/lc98.md)
- [98. 验证二叉搜索树](./day20/lc98.md)
- [day 21](./day21.md)
- [530. 二叉搜索树的最小绝对差](./day21/lc530.md)
- [501. 二叉搜索树中的众数](./day21/lc501.md)
- [236. 二叉树的最近公共祖先](./day21/lc236.md)
- [day 22](./day22.md)
- [235. 二叉搜索树的最近公共祖先](./day22/lc235.md)
- [701. 二叉搜索树中的插入操作](./day22/lc701.md)
- [450. 删除二叉搜索树中的节点](./day22/lc450.md)
30 changes: 30 additions & 0 deletions notes/src/day21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 第六章 二叉树part07
今日内容

● 530.二叉搜索树的最小绝对差
● 501.二叉搜索树中的众数
● 236. 二叉树的最近公共祖先

详细布置

## 530.二叉搜索树的最小绝对差

需要领悟一下二叉树遍历上双指针操作,优先掌握递归
题目链接/文章讲解:https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E5%B7%AE.html
视频讲解:https://www.bilibili.com/video/BV1DD4y11779

## 501.二叉搜索树中的众数

和 530差不多双指针思路,不过 这里涉及到一个很巧妙的代码技巧。

可以先自己做做看,然后看我的视频讲解。

https://programmercarl.com/0501.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E4%BC%97%E6%95%B0.html
视频讲解:https://www.bilibili.com/video/BV1fD4y117gp

## 236. 二叉树的最近公共祖先

本题其实是比较难的,可以先看我的视频讲解

https://programmercarl.com/0236.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html
视频讲解:https://www.bilibili.com/video/BV1jd4y1B7E2
32 changes: 32 additions & 0 deletions notes/src/day21/lc236.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 236. 二叉树的最近公共祖先

## 题目描述
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

## 解题思路
```cpp
class Solution {
public:
TreeNode*pp;
TreeNode*res=0;
TreeNode*qq;
int f(TreeNode*r){
if(!r)return 0;
int left=f(r->left);int right=f(r->right);
int a=r==pp||r==qq?1:0;
a+=left+right;
if(!res&&a==2){res=r;}return a;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
pp=p;qq=q;
f(root);
return res;
}
};
```
f表示在子树中找到的个数,找到2个的时候就设置res就行了
## 学习感想
49 changes: 49 additions & 0 deletions notes/src/day21/lc501.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 501. 二叉搜索树中的众数

## 题目描述

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树

## 解题思路

对我来说有点难了

```cpp
class Solution {
public:
TreeNode*pre=0;
int cnt=0;
int maxcnt=0;
vector<int>res;
void f(TreeNode*p){
if(!p)return;
f(p->left);
if(!pre)cnt=1;else{
if(p->val==pre->val)cnt ++;
else cnt=1;
}
if (cnt>maxcnt){
maxcnt=cnt;res.clear();res.push_back(p->val);
} else if (cnt==maxcnt){
res.push_back(p->val);
}
pre=p;
f(p->right);
}
vector<int> findMode(TreeNode*r) {
res.clear();
f(r);
return res;
}
};

```
## 学习感想
73 changes: 73 additions & 0 deletions notes/src/day21/lc530.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# 530. 二叉搜索树的最小绝对差

## 题目描述

给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

差值是一个正数,其数值等于两值之差的绝对值。

## 解题思路

一开始没有理解题意写出来的代码,只考虑了一个节点左边和右边,没考虑相隔两层的情况

```cpp
class Solution {
public:
int getMinimumDifference(TreeNode*r) {
if(!r)return 1<<30;
int res = 1<<30;
if(r->left){
int a=r->val-r->left->val;
res=min(res,a);
int b=getMinimumDifference(r->left);
res=min(res,b);
}
if(r->right){
int a=r->right->val-r->val;
res=min(res,a);
int b=getMinimumDifference(r->right);
res=min(res,b);
}

return res;
}
};
```

```cpp
class Solution {
public:
vector<int>v;
void f(TreeNode*r){if(!r)return;f(r->left);v.push_back(r->val);f(r->right);}
int getMinimumDifference(TreeNode*r) {
v.clear();
f(r);
int a=INT_MAX;
for(int i=1;i<v.size();i++)a=min(a,v[i]-v[i-1]);
return a;
}
};
```
遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。
二叉搜索树顺序遍历:
```cpp
class Solution {
public:
int res = INT_MAX;
TreeNode* pre = NULL;
void f(TreeNode*r){
if(!r)return;
f(r->left);
if(pre){res=min(res,r->val-pre->val);}
pre=r;
f(r->right);
}
int getMinimumDifference(TreeNode*r) {
f(r);
return res;
}
};
```
## 学习感想
29 changes: 29 additions & 0 deletions notes/src/day22.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# 第六章 二叉树part08
今日内容:

● 235. 二叉搜索树的最近公共祖先
● 701.二叉搜索树中的插入操作
● 450.删除二叉搜索树中的节点

详细布置

## 235. 二叉搜索树的最近公共祖先

相对于 二叉树的最近公共祖先 本题就简单一些了,因为 可以利用二叉搜索树的特性。

题目链接/文章讲解:https://programmercarl.com/0235.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html
视频讲解:https://www.bilibili.com/video/BV1Zt4y1F7ww

## 701.二叉搜索树中的插入操作

本题比想象中的简单,大家可以先自己想一想应该怎么做,然后看视频讲解,就发现 本题为什么比较简单了。

题目链接/文章讲解:https://programmercarl.com/0701.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E6%8F%92%E5%85%A5%E6%93%8D%E4%BD%9C.html
视频讲解:https://www.bilibili.com/video/BV1Et4y1c78Y

## 450.删除二叉搜索树中的节点

相对于 插入操作,本题就有难度了,涉及到改树的结构

题目链接/文章讲解:https://programmercarl.com/0450.%E5%88%A0%E9%99%A4%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html
视频讲解:https://www.bilibili.com/video/BV1tP41177us
31 changes: 31 additions & 0 deletions notes/src/day22/lc235.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 235. 二叉搜索树的最近公共祖先

## 题目描述

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

## 解题思路

当pq同时在两边的话,就是找到了;不是的话,那肯定就是在某一边

```cpp
class Solution {
public:
int mi, ma;
TreeNode*f(TreeNode*r){
if(!r)return 0;
if(mi<=r->val&&r->val<=ma)return r;
if(mi>r->val)return f(r->right);return f(r->left);
}
TreeNode* lowestCommonAncestor(TreeNode* r, TreeNode* p, TreeNode* q) {
mi=min(p->val,q->val);
ma=max(p->val,q->val);
return f(r);
}
};
```
## 学习感想
40 changes: 40 additions & 0 deletions notes/src/day22/lc450.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 450. 删除二叉搜索树中的节点

## 题目描述

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点;
如果找到了,删除它。

## 解题思路

思路:使用子树代替删除的节点。如果都有的话,随意左还是右。

通用选择右子树,那么子树的子树如何处理?右子树的右子树变成右子树,右子树的左子树变成被删除节点子树上最右侧叶节点的子树。

```cpp
class Solution {
public:
int k;
TreeNode*f(TreeNode* r) {if(!r)return r;
if(r->val==k) {
if(!r->left&&!r->right)return 0;
if(!r->left)return r->right;
if(!r->right)return r->left;
TreeNode*save=r->right->left;
r->right->left=r->left;
r=r->right;TreeNode*p=r->left;
while(p->right)p=p->right;p->right=save;
return r;
}
if (r->val<k)r->right=f(r->right);else r->left=f(r->left);return r;
}
TreeNode* deleteNode(TreeNode* r, int key) {
k=key;r=f(r);return r;
}
};
```
## 学习感想
26 changes: 26 additions & 0 deletions notes/src/day22/lc701.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 701. 二叉搜索树中的插入操作

## 题目描述

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

## 解题思路

```cpp
class Solution {
public:
int v;
TreeNode*f(TreeNode*r) {if(!r)return new TreeNode(v);
if(r->val<v)r->right=f(r->right);else r->left=f(r->left);return r;
}
TreeNode* insertIntoBST(TreeNode* r, int val) {
v=val;r=f(r);return r;
}
};
```
WA: 输入的树可能为空树
## 学习感想

0 comments on commit 30e1344

Please sign in to comment.