代码随想录刷题day21
530.二叉搜索树的最小绝对差
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例:
输入:root = [4,2,6,1,3]
输出:1
思路:中序遍历二叉搜索树(递增),每次计算当前节点与前一个节点的差值,更新最小值,更新前一个指针。
class Solution {
public:
TreeNode* pre = nullptr;//前一个节点
int minValue = INT_MAX;//最小绝对差
void travasal(TreeNode* root){//中序遍历
if(root == nullptr) return;
travasal(root->left);
if(pre != nullptr)
minValue = min(minValue, root->val - pre->val);
pre = root;
travasal(root->right);
}
int getMinimumDifference(TreeNode* root) {
travasal(root);
return minValue;
}
};
501.二叉搜索树中的众数
给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
- 结点左子树中所含节点的值 小于等于 当前节点的值
- 结点右子树中所含节点的值 大于等于 当前节点的值
- 左子树和右子树都是二叉搜索树
思路:
中序遍历二叉搜索树,指针pre记录上一个节点
每次遍历一个节点时,更新当前节点的频率,更新pre指针,更新最大频率,更新结果集
最后返回结果数组即可
class Solution {
public:
int count = 0;//当前节点频率
int maxCount = 0;//最大的频率
TreeNode* pre = nullptr;//前一个节点
vector<int> res;//结果集
//中序遍历
void travasal(TreeNode* cur){
if(cur == nullptr) return;
travasal(cur->left);//左
if(pre == nullptr) count = 1;//第一个节点
else if(pre->val == cur->val) count++;//节点值相等,count值+1
else count = 1;//节点值不等,频率归1
pre = cur;//更新前一个节点
if(count == maxCount) res.push_back(cur->val);
if(count > maxCount){
maxCount = count;
res.clear();
res.push_back(cur->val);
}
travasal(cur->right);//右
}
vector<int> findMode(TreeNode* root) {
travasal(root);
return res;
}
};
236. 二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 :
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。
思路:
后序遍历左右中可以将结果一层一层返回到根节点,实现从下到上的遍历,找到最近公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == p || root == q || root == NULL) return root;
//后序遍历
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left != NULL && right != NULL) return root;
if(left == NULL) return right;
return left;
}
};
流程图帮助理解
总结:
- 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从低向上的遍历方式。
- 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
- 要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。