代码随想录算法训练营第二十三天| 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

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

题目链接/文章讲解: 代码随想录

解题思路

最小绝对差我的思路是肯定出现在相邻节点处,然后利用双指针一个cur,一个pre,两个作差遍历,记录最小值即可。主要重要的是双指针的思路,与验证二叉搜索树是一样的思路,注意二叉搜索树一定要中序

class Solution {
private:
 int result = INT32_MAX;
 TreeNode* pre = nullptr;
public:
    void travelSal(TreeNode* cur)
    {
           if(cur==nullptr) return; //空节点就返回
           travelSal(cur->left);   //去搜左边
           if(pre!=nullptr) result = min(result,cur->val - pre->val);   //中节点处理
           pre = cur;
           travelSal(cur->right);  //再搜右边
    }

    int getMinimumDifference(TreeNode* root) {
                travelSal(root);
                return result;
    }
};

 501.二叉搜索树中的众数

题目链接/文字讲解:

解题思路

如果是普通二叉树,我想的就是利用map存放,然后利用小顶堆排除出现频率小的元素。但这里是搜索树,众数是连续出现的,那么我们利用双指针即可,但这里涉及一个技巧。只需要遍历一遍,当我们遇到更大的count时,那么就更新最大值,并清空结果集,非常类似于之前的滑动窗口最大值,维护可能的最大值

class Solution {
private:
  int count =0;
  int maxCount = 0;
  vector<int> result;
  TreeNode* pre;
public:
   void search(TreeNode* cur)
   {
         //终止条件,当我们遍历到空节点的时候就返回,因为他不需要计数
         if(cur==nullptr) return;
         //因为是二叉搜索树,因此我们利用中序遍历
         search(cur->left); //左
         //中的处理逻辑
         if(pre==nullptr) count=1;   //第一个节点
         else if(pre->val==cur->val) count++;   //如果不是第一个节点,且上一个数值等于这一个数值,那么就计数器+1
         else count = 1;     //如果遇到不相等的数值了,那么计数器归1
         pre = cur;    //将指针变为现在
         if(count == maxCount) result.push_back(pre->val);
         else if (count> maxCount)    //如果后面出现了,比我之前还要大的数量,那么之前的就全部清空,之前的叫局部最优解,进行状态迭代
         {
                maxCount = count;
                result.clear();
                result.push_back(pre->val);
         }
         search(cur->right);   //去搜索右边
   }

    vector<int> findMode(TreeNode* root) {
           search(root);
           return result;
    }
};

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

题目链接/文字讲解:代码随想录

解题思路

我们从底向上搜索,利用后续遍历,当遇到了p或者q就向上返回,当左子树和右子树出现了q和p,那么中就是最近公共祖先,但如果遇到了情况2,他已经被包含在情况1了

 

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
          if(root==nullptr) return nullptr;   //遇到空节点就返回
          if(root==p || root==q)  return root;   //如果遇到符合条件的节点,直接把节点返回
          //单层逻辑
          TreeNode* left = lowestCommonAncestor(root->left,p,q);
          TreeNode* right = lowestCommonAncestor(root->right,p,q);    //向孩子去搜集信息,给中处理
          if(left != nullptr && right !=nullptr) return root; //左右孩子都不为空,这说明自身是最近公共祖先
          else if (left ==nullptr && right !=nullptr) return right;
          else if(left!=nullptr && right==nullptr) return left;      
          return nullptr;    //左右孩子都为空,就返回空给上层
    }
};

收获

继续努力

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值