代码随想录刷题随记18-二叉树7

文章讲述了在二叉搜索树中解决三个问题:计算最小绝对差,找到众数,以及找到最近公共祖先的算法。作者通过中序遍历和回溯思想,利用递归实现了高效的解决方案。
摘要由CSDN通过智能技术生成

代码随想录刷题随记18-二叉树7

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

leetcode链接
注意是搜索二叉树所以是有序的,所以如果按照中序遍历的话,最近差异的只会存在于前后遍历的两个节点之间,而不会出现跨界的的问题。

class Solution {
public:
    int getMinimumDifference(TreeNode* root) {
         int difmin=INT_MAX;
         stack<TreeNode * > mystack;
         TreeNode * cur=root;
         TreeNode * pre=nullptr;
         while(cur!=nullptr||!mystack.empty()){
            if(cur!=nullptr){
                mystack.push(cur);
               cur=cur->left;
            }
            else{
                cur=mystack.top();
                mystack.pop();
                if(pre!=nullptr){
                    int tmp=abs(cur->val-pre->val);
                    if(tmp<difmin){
                        difmin=tmp;
                    }
                }
                pre=cur;
                cur=cur->right;
            }

         }
         return difmin;
    }
};

二叉搜索树中的众数

leetcode 链接
如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。
因为二叉搜索树的中序遍历是有序的所以,相同的数字一定是挨着的,所以当统计到新的数的时候之前的数以及完全统计完了
解题代码:

class Solution {
public:
    vector<int> findMode(TreeNode* root) {
      TreeNode * cur=root;
      TreeNode * pre=nullptr;
      int cnt=0;
      int cntcur=0;
      stack<TreeNode *> mystack;
      vector<int> ret;
      while(cur!=nullptr||!mystack.empty()){
        if(cur!=nullptr){
          mystack.push(cur);
          cur=cur->left;
        }
        else{
            cur=mystack.top();
            mystack.pop();
            if(pre==nullptr)
               cntcur++;
            if(pre!=nullptr){
                if(pre->val==cur->val){
                    cntcur++;                   
                }
                else{
                    cntcur=1;
                }
            }
                if(cntcur>cnt){
                   cnt=cntcur;
                    //清楚很重要
                    ret.clear();
                    ret.push_back(cur->val);                 
                }
                else if(cntcur==cnt){
                      ret.push_back(cur->val);
                    }
                
            
            pre=cur;
            cur=cur->right;
        }
      }
      
      return ret;
    }
};

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

leetcode链接
遇到这个题目首先想的是要是能自底向上查找就好了,这样就可以找到公共祖先了。
后序遍历(左右中)就是天然的回溯过程,可以根据左右子树的返回值,来处理中节点的逻辑。

struct info{
     bool findp;
     bool findq;
     bool iscommen;
     TreeNode * commonnode;
 };
class Solution {
public:
    info* subtask(TreeNode* root, TreeNode* p, TreeNode* q){
        info* ret=new info();
        if(root==nullptr){
            ret->findp=false;
            ret->findq=false;
            ret->iscommen=false;
            ret->commonnode=nullptr;
            return ret;

        }
        info* left=subtask(root->left, p, q);
        info* right=subtask(root->right, p, q);
        if(left->iscommen||right->iscommen){
            ret->findp=true;
            ret->findq=true;
            ret->commonnode=left->iscommen?left->commonnode:right->commonnode;
            ret->iscommen=true;
        }
        else if((left->findp&&right->findq)||(left->findq&&right->findp)){
            ret->findp=true;
            ret->findq=true;
            ret->iscommen=true;
            ret->commonnode=root;
        }
        else if((root==q&&left->findp)||(root==q&&right->findp)||(root==p&&left->findq)||(root==p&&right->findq)){
            ret->findp=true;
            ret->findq=true;
            ret->iscommen=true;
            ret->commonnode=root;
        }
        else{

            ret->findp=(left->findp||right->findp||root==p);
            ret->findq=left->findq||right->findq||root==q;
            ret->commonnode=nullptr;
            ret->iscommen=false;
        }
        return ret;

    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root==nullptr)
          return nullptr;
     info* ret=subtask(root,p, q)   ;
     return ret->commonnode;
    }
};
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值