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

LeetCode530二叉搜索树的最小绝对差

关键点:这道题目不是返回整个数中任意两个节点val的差值。而是比较父节点 左子节点 右子节点 三个数之间的差值。以上的解释有误,其实还是找的全局最小的差值,只不过因为是二叉搜索树,他有前后顺序的。 所以最小的差值一定是相邻的,所以两个指针一个pre 一个cur(就是当前root)比较差值即可。
关于返回值问题,这里使用了一个全局变量 result来记录结果,就不用再在递归里面加返回值了。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    TreeNode pre;
    int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        // 这道题目不是返回整个数中任意两个节点val的差值.
        // 而是比较父节点 左子节点 右子节点 三个数之间的差值。

        // 以上的解释有误,其实还是找的全局最小的差值,只不过因为是二叉搜索树,他有前后顺序的。
        // 所以最小的差值一定是相邻的,所以两个指针一个pre 一个cur(就是当前root)比较差值即可
        if(root == null){
            return 0;
        }
        getResult(root);
        return result;
    }
    public void getResult(TreeNode root){
        if(root == null){
            return;
        }
        // 左
        getResult(root.left);

        // 中
        if(pre != null){
            result = Math.min(result, root.val - pre.val);
        }
        pre = root; // 叶子结点首先赋值给pre,后面是没计算一次将当前root赋值给pre,root变成下一个
        getResult(root.right);
    }
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
private:
    vector<int> nums;
    void getNums(TreeNode* node){
        if(node == NULL) return;
        getNums(node->left);
        nums.push_back(node->val);
        getNums(node->right);
    }
public:
    int getMinimumDifference(TreeNode* root) {
        getNums(root);
        int fast = 1;

        int slow = 0;
        int ans = INT_MAX;
        while(fast<nums.size()){
            if(ans > (nums[fast] - nums[slow])){
                ans = nums[fast] - nums[slow];
            }
            fast++;
            slow++;
        }
        return ans;

    }
};

双指针的方法,利用中序遍历结合双指针的方法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
private:
    int ans = INT_MAX;
    TreeNode* pre = NULL;
    void getNums(TreeNode* node){
        if(node == NULL) return;
        getNums(node->left);
        if(pre != NULL){
            ans = min(ans, node->val - pre->val);
        }
        pre = node;
        getNums(node->right);
    }
public:
    int getMinimumDifference(TreeNode* root) {
    
    getNums(root);
    return ans;
    }
};

LeetCode501二叉搜索树中的众数

一开始想用遍历普通二叉树那样,将结果都放到一个map里面,最后得到出现次数最多的数。

思路:结合二叉搜索树的特性,就相当于处理一个数组。只不过不能像处理数组一样,直接从前往后遍历。而是递归,利用双指针比较前后两个元素,同时更新count,最后比较countmaxCount,如果出现了 > > > = = =就要开始更新MAxcount并记录当前的root.val.

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    TreeNode pre = null;
    int count =0;
    int MaxCount=0;
    ArrayList<Integer> list = new ArrayList<>();
    public int[] findMode(TreeNode root) {
        find(root);
        int[] res = new int[list.size()];
        for(int i=0;i<list.size();i++){
            res[i] = list.get(i);
        }
        return res;
    }
    public void find(TreeNode root){
        // 直接在中序遍历的过程中就把结果计算出来
        // 可以联想数组的操作
        if(root == null){
            return;
        }
        find(root.left);
        if(pre == null || pre.val != root.val){ // 这里一定要写成这种情况,不然pre!=null的话在叶子结点的时候回不满足,因为一开始的pre==null的。
            count=1;
        }
        else{
            count++;
        }
        // 处理maxCount
        if(count > MaxCount){
            list.clear();
            list.add(root.val);
            MaxCount = count;
        }
        else if(count==MaxCount){ // 不可以与上面得if结合因为这里的逻辑是当出现两个一样个数的[2, 2, 3, 3]是,直接吧3也添加到list里面。若是,加到上面就是导致2被删除。
            list.add(root.val);
        }
        pre = root;
        find(root.right);
    }
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
private:
    vector<int> ans;
    int count = 0;
    int maxCount = INT_MIN;
    TreeNode* pre = NULL;
    void traversal(TreeNode* node){
        if(node == NULL) return;
        traversal(node->left);
        if(pre == NULL){
            count = 1;
        }
        else if(pre->val == node->val){
            count++;
        }
        else{
            count = 1;
        }
        pre = node;
        if(count > maxCount){
            ans.clear();
            ans.push_back(node->val);
            maxCount = count;
        }
        else if(count == maxCount){
            ans.push_back(node->val);
        }
        traversal(node->right);

    }
    
public:
    vector<int> findMode(TreeNode* root) {
        traversal(root);
        return ans;
    }
};

LeetCode236二叉树的最近公共祖先

模板题
思路:回溯+自底向上+递归+后序遍历(左右中)。
使用回溯,找到了p就返回p,找了了q就返回q。如果找到了他们的父节点就返回这个父节点。后序:因为只有使用后序在可以实现自底向上。不适用迭代是因为迭代不适合模拟回溯(回溯和迭代天生一对)。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root ==q){ // 终止条件:如果遇到了空节点返回null 
        // 如果遇到了p或q 就返回p或q
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q); // 左
        TreeNode right = lowestCommonAncestor(root.right, p, q); // 右

        if(left == null && right== null){   // 如果左节点或右节点都是null那就向上返回null
            return null;
        }
        else if(left == null && right != null){ // 如果右节点不为空,那就返回right的值,此时可能是p也肯是q 也可能是找到的结果 一直返回到根节点
            return right;
        }
        else if(left != null && right == null){ // 同理
            return left;
        }
        else{ // (left != null && right != null) 这里就是父节点的情况,向上返回父节点。
            return root;
        }
    }
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
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 NULL; // 从叶子节点返回的null,如果没有找到q,p 就接着向上返回NULL
        else if(left != NULL && right == NULL) return left; // left不为NULL,表示左边找到了一个q或p,但是right为NULL。直接向上返回left
        else if(left == NULL && right != NULL) return right; // 同理
        else return root;  // 这里就是left和right都找到了,因此要返回当前父节点root
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值