代码随想录第二十一天

代码随想录第二十一天

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

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

题目链接: 二叉搜索树的最小绝对差
自己的思路:和验证二叉搜索树一样的思路!可以求每个相邻节点的差值的绝对值,然后和之前的差值的绝对值进行比较,取最小的为新的res;递归三部曲:1、传入参数:当前节点;2、终止条件:如果当前节点为空,直接返回;3、单层递归逻辑:中序遍历!!因为中序遍历可以保证是递增的,这样就不会跳着比较,所以先递归左子树,然后中节点和前一个节点求差值的绝对值和res比较,取最小值为res,然后再定义新的pre,再进行右子树的遍历即可!!!

正确思路:

代码:

class Solution {
    int res = Integer.MAX_VALUE;
    TreeNode pre;
    public int getMinimumDifference(TreeNode root) {
        if (root==null) return 0;
        getmin(root);
        return res;
    }
    
    public void getmin(TreeNode root){
        if (root==null) return;
        //左递归
        getmin(root.left);
        //求上一个节点和此节点的最小值和之前的差进行比较
        if (pre!=null){
            res = Math.min(res,Math.abs(pre.val-root.val));
        }
        //重新表示上一个节点
        pre = root;
        //右递归
        getmin(root.right);
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

Leetcode 501. 二叉搜索树中的众数

题目链接: 二叉搜索树中的众数
自己的思路:没想到!!!!

正确思路:比较笨的方法是遍历两次二叉树,然后找其中最大的值就可以;但是这里是使用了一点代码技巧来处理这个问题,所以使用一次遍历就可以;具体的思路为:二叉搜索树一定是中序遍历!!!!这样可以保证有序,主要是处理中的逻辑,我们可以定义三个变量,count用于存储当前结点的值出现的次数,maxcount用于存储出现的最多的结点出现的次数,pre存储上一个节点;首先是计数阶段:当pre是空的时候,那也就是说node现在是出于叶子节点,记录它的count值为1,当pre的结点值等于node的结点值的时候,说明出现了相同的节点值,则count++,当pre的结点值不等于node的结点值时,说明出现了不同的节点值,重置count为1;然后是加入结果阶段:当count==maxcount的时候,说明当前的次数和最大的次数相同,当前结点值加入到结果集中,如果count>maxcount的时候,说明之前的maxcount并不是全局的最大,所以把之前的res中的所有元素清空,然后再加入新的结果,并且把maxcount赋值为count;递归三部曲:1、传入参数:当前节点;2、终止条件:当当前节点为空的时候,返回;3、单层逻辑:先左递归,然后处理中间节点,然后右递归!!!

代码:

class Solution {
    List<Integer> res = new ArrayList<>();
    int count = 0;
    int maxcount = 0;
    TreeNode pre;
    public int[] findMode(TreeNode root) {
        addMode(root);
        int [] re = new int[res.size()];
        for (int i =0;i<re.length;i++){
            re[i] = res.get(i);
        }
        return re;
    }
    public void addMode(TreeNode node){
        if (node==null) return;
        addMode(node.left);

        //计数阶段
        if (pre==null) count=1;
        else if (pre.val==node.val){
            count++;
        }
        else count=1;

        //加结果阶段
        if (count>maxcount){
            maxcount = count;
            res.clear();
            res.add(node.val);
        }else if (count==maxcount){
            res.add(node.val);
        }
        pre = node;
        addMode(node.right);
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

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

题目链接: 二叉树的最近公共祖先
自己的思路:没想到!!!

正确思路:主要是遍历顺序,使用后序遍历出来,自底向上地返回;递归三部曲:1、传入参数:当前结点、结点p、结点q;2、终止条件:当当前结点是空或者p和q时,直接返回当前结点即可,因为没有比这个更深的结点了;3、单层递归逻辑:先左右递归左右子树查找左右子树分别对p和q的最近公共祖先,得到left和right,如果两个都为空,说明没找到,直接返回null,如果其中一个不为空,另一个为空,说明不为空的那个为最近公共祖先,如果两个都不为空,则当前节点为最近公共祖先!!!
代码:

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //如果当前结点就是空或者p和q的话,直接返回当前结点
        if (root==null||root==p||root==q){
            return root;
        }
        //递归左右子树
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        //如果左右两边都没有,直接返回null
        if (left==null&&right==null) return null;
        //左边有返回左边,右边有返回右边
        if (left==null||right==null){
            return left==null?right:left;
        }
        //左右两边都有返回当前结点
        return root;
    }
}

复杂度分析
时间复杂度: O ( n ) \mathcal{O}(n) O(n)
空间复杂度: O ( 1 ) \mathcal{O}(1) O(1)

你可能感兴趣的:(数据结构,java,开发语言,算法,深度优先)