算法刷题 Day 21 | 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先

今日内容

  • 530.二叉搜索树的最小绝对差
  • 501.二叉搜索树中的众数
  • 236. 二叉树的最近公共祖先   

详细布置

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

需要领悟一下二叉树遍历上双指针操作,优先掌握递归

题目链接/文章讲解:https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E5%B7%AE.html

视频讲解:https://www.bilibili.com/video/BV1DD4y11779

Tips:

题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。

注意是二叉搜索树,二叉搜索树可是有序的。

遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。

最直观的想法,就是把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。但其实在二叉搜素树中序遍历的过程中,我们就可以直接计算了。需要用一个pre节点记录一下cur节点的前一个节点。

这里记录pre节点和最终结果需要用到全局变量。同时要记得在中序遍历后及时更新Pre节点。

我的题解:

class Solution {
public:
    int result = INT_MAX;
    TreeNode* pre = NULL;
    void travelsal(TreeNode* node){
        if(node == NULL) return;
        travelsal(node->left);
        if(pre!=NULL){
            int difference = node->val - pre->val;
            result = result < difference ? result : difference;
        }
        // 记得更新Pre节点
        pre = node;
        travelsal(node->right);
    }   

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

501.二叉搜索树中的众数

和 530差不多双指针思路,不过 这里涉及到一个很巧妙的代码技巧。

可以先自己做做看,然后看我的视频讲解。

https://programmercarl.com/0501.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%AD%E7%9A%84%E4%BC%97%E6%95%B0.html

视频讲解:https://www.bilibili.com/video/BV1fD4y117gp

Tips:这一题思路倒是很好理解,但就是实现时候的细节需要注意

1. 注意对第一个节点的处理逻辑

2. 注意更新pre指针

我的题解:

class Solution {
public:
    TreeNode* pre = NULL;
    vector<int> mode;
    int maxCount = 0;
    int count = 0;

    void traversal(TreeNode* root){
        if(root == NULL){
            return;
        }

        traversal(root->left);
        
        if(pre == NULL || pre->val == root->val){
            count++;
        }
        else if(pre->val != root->val){
            count = 1;
        }

        pre = root;

        if(count == maxCount){
            mode.push_back(root->val);
        }

        if(count > maxCount){
            maxCount = count;
            mode.clear();
            mode.push_back(root->val);
        }

        traversal(root->right);
        return;
    }

    vector<int> findMode(TreeNode* root) {
        traversal(root);
        return mode;
    }
};

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

本题其实是比较难的,可以先看我的视频讲解

https://programmercarl.com/0236.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91%E5%85%AC%E5%85%B1%E7%A5%96%E5%85%88.html

视频讲解:https://www.bilibili.com/video/BV1jd4y1B7E2

Tips:这道题用到了回溯的思想。需要认真审题,题目中说了p 和 q 均存在于给定的二叉树中。因此不需要考虑有一个节点或两个节点都不存在于二叉树中的情况,也正是因此,在代码开头遇到 q 或者 p 就返回,这样也包含了 q 或者 p 本身就是 公共祖先的情况。

我的题解:

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //遇到 q 或者 p 就返回,这样也包含了 q 或者 p 本身就是 公共祖先的情况
        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;
    }
    else if(left!= NULL && right == NULL){
        return left;
    }
    else if(left == NULL && right != NULL){
        return right;
    }
    else{
        return NULL;
    }

    }
};

 

posted @ 2023-01-28 12:47  GavinGYM  阅读(61)  评论(0)    收藏  举报