Day21
530 .二叉搜索树的最小绝对差
与验证二叉搜索树区别不大,重点还是遍历二叉搜索树。
递归法:中序遍历(二叉搜索树符合中序遍历)
class Solution {
public:
TreeNode* pre;
int result=INT_MAX;
void travel(TreeNode* root){
if(root==NULL) return;
travel(root->left);
if(pre!=NULL&&root->val-pre->val<result){
result=root->val-pre->val;
}
pre=root;
travel(root->right);
return;
}
int getMinimumDifference(TreeNode* root) {
travel(root);
return result;
}
};
迭代法实现中序遍历
使用的是中序的迭代法,而不是统一迭代法。
class Solution {
public:
int getMinimumDifference(TreeNode* root) {
stack<TreeNode*> st;
TreeNode* pre;
TreeNode* cur=root;
int result=INT_MAX;
while(cur!=NULL || !st.empty()){
if(cur!=NULL){
st.push(cur);
cur=cur->left;
}
else{
cur=st.top();st.pop();
if(pre!=NULL&&cur->val-pre->val<result){
result=cur->val-pre->val;
}
pre=cur;
cur=cur->right;
}
}
return result;
}
};
501.二叉搜索树中的众数
重点是找到所有的众数,所以要存下来。
按照正常的二叉树搜索(不考虑二叉搜索树的性质):
class Solution {
public:
void searchBST(TreeNode* node,unordered_map<int,int>& umap){
if(node==NULL) return;
searchBST(node->left,umap);
umap[node->val]++;
searchBST(node->right,umap);
return;
}
bool static cmp(pair<int,int>& a,pair<int,int>& b ){
return a.second>b.second;
}
vector<int> findMode(TreeNode* root) {
unordered_map<int,int> umap;
searchBST(root,umap);
vector<int> result;
vector<pair<int, int>> vec(umap.begin(), umap.end());
sort(vec.begin(),vec.end(),cmp);
result.push_back(vec[0].first);
for(int i=1;i<vec.size();i++){
if(vec[i].second==vec[0].second) result.push_back(vec[i].first);
else break;
}
return result;
}
};
cmp的定义
按照搜索二叉树的性质
按中序遍历:
class Solution {
public:
int maxCount=0;
int count=0;
TreeNode*pre=NULL;
vector<int> travelsal(TreeNode* node,vector<int>& result){
if(node==NULL) return result;
travelsal(node->left,result);
if(pre!=NULL && node->val==pre->val){
count++;
}
else{
count=1;
}
pre=node;
if(count==maxCount){
result.push_back(node->val);
}
if(count>maxCount){
result.clear();
result.push_back(node->val);
maxCount=count;
}
travelsal(node->right,result);
return result;
}
vector<int> findMode(TreeNode* root) {
vector<int> result;
travelsal(root,result);
return result;
}
};
这个代码可以改进,将result放到外面,这样就不用每次都返回值了。还有一点一定要先判断相等,再判断要不要该maxCount,不然最后会添加两次值。
迭代
class Solution {
public:
vector<int> findMode(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
TreeNode* cur=root;
TreeNode* pre=NULL;
int maxCount=0;
int count=0;
while(cur!=NULL || !st.empty()){
if(cur!=NULL){
st.push(cur);
cur=cur->left;
}
else{
cur=st.top();
st.pop();
if(pre==NULL){
count=1;
}
else if(pre->val==cur->val){
count++;
}
else{count=1;}
if(count==maxCount){
result.push_back(cur->val);
}
if(count>maxCount){
maxCount=count;
result.clear();
result.push_back(cur->val);
}
pre=cur;
cur=cur->right;
}
}
return result;
}
};
一定不要忘记初始化,一定不要忘记初始化,一定不要忘记初始化!!!!
236. 二叉树的最近公共祖先
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 right;
else if(left!=NULL&&right==NULL) return left;
else if(left!=NULL&&right!= NULL) return root;
else return NULL;
}
};
重点是考虑清楚,本题应该使用回溯的思想,所以后序比较合适,因为要比较左右子树传过来的情况,所以应该是遍历全树的(也就是把left和right传过来的值保留下来);
如何保存找到的祖先节点也要想清楚,左边为空右边不为空,这时候有两种可能,1.右边已经找到了两个节点,传过来的是祖先节点,2.右边找到了其中一个。
需要修改祖先节点的时候就是左右都变化的时候
还需要考虑一种情况就是p是q的祖先节点,这种情况图中也是包含的,首先一定能找到两个节点,当查找完全树只找到其中之一的时候就说明是这种情况(也就是找到其中的一个节点的时候就返回了)。