day21 2023/02/21
一、二叉搜索树的最小绝对差
给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。
注意是二叉搜索树,二叉搜索树可是有序的。
那么二叉搜索树采用中序遍历,其实就是一个有序数组。
在一个有序数组上求两个数最小差值,这是不是就是一道送分题了
分析如下:
思路一、将改二叉搜索树的中序遍历结果转换为一个数组,即转换为数组两个数的最小差值
思路二、采取递归法:
但是要考虑双指针法
如图所示:
代码如下:
思路一的代码:
class Solution {
public:
vector<int> vec;
void Traversal(TreeNode* root)
{
if(root==NULL) return;
Traversal(root->left);
vec.push_back(root->val);
Traversal(root->right);
}
int getMinimumDifference(TreeNode* root) {
Traversal(root);
int res=INT_MAX;
for(int i=0;i<vec.size()-1;i++)
{
if(res>abs(vec[i+1]-vec[i]))
res=abs(vec[i+1]-vec[i]);
}
return res;
}
};
思路二的代码:
class Solution {
public:
int res=INT_MAX;
TreeNode* pre=NULL;
int getMinimumDifference(TreeNode* root) {
if(root==NULL) return 0;
TreeNode* cur=root;
int left=getMinimumDifference(cur->left);
if(pre!=NULL)
{
res=min(res,cur->val-pre->val);
}
pre=cur;
int right=getMinimumDifference(cur->right);
return res;
}
};
二、二叉搜索树中的众数
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
- 结点左子树中所含结点的值小于等于当前结点的值
- 结点右子树中所含结点的值大于等于当前结点的值
- 左子树和右子树都是二叉搜索树
分析如下:
思路一、把整个树都遍历了,用map统计频率
思路二、双指针法
代码如下:
思路一代码:
class Solution {
public:
void Traversal(TreeNode* cur,unordered_map<int,int>& map)
{
if(cur==NULL) return;
map[cur->val]++;
Traversal(cur->left,map);
Traversal(cur->right,map);
return ;
}
bool static cmp(pair<int,int> a1,pair<int,int> a2)
{
return a1.second>a2.second;
}
vector<int> findMode(TreeNode* root) {
vector<int> res;
unordered_map<int,int> map;
Traversal(root,map);
vector<pair<int,int>> vec(map.begin(),map.end());
sort(vec.begin(),vec.end(),cmp);
res.push_back(vec[0].first);
for(int i=1;i<vec.size();i++)
{
if(vec[i].second==vec[0].second)
res.push_back(vec[i].first);
else
break;
}
return res;
}
};
思路二的代码:(后面有时间再来补上)
三、二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
分析如下:
使用递归的方法求解
-
求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
-
在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
-
要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。
代码如下:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL||root==p||root==q)
return root;
TreeNode* left=lowestCommonAncestor(root->left,p,q);
TreeNode* right=lowestCommonAncestor(root->right,p,q);
if(left!=NULL&&right!=NULL)
return root;
else if(left==NULL&&right!=NULL)
return right;
else if(left!=NULL&&right==NULL)
return left;
else
return NULL;
}
};