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

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

题目链接:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

 思路:也是利用二叉搜索树都性质,把他当成一个有序数组来看,就是求相邻两个元素的差,取最小那个;可以中序遍历做成数组来看,也可以递归的过程来处理

递归时用到当前结点和上一个结点,pre cur ;如果pre为空,就是第一次,加个判断不管他

    public void getMin(TreeNode node) {
        if(node == null) return;
        getMin(node.left);//左
        if(pre != null){//中
            int difference = node.val - pre.val;
            if(difference < minResult) minResult = difference;
        }
        pre = node;
        getMin(node.right);//右
        return;
    }

递归也可以转化成迭代,中序遍历的迭代:

public int getMinimumDifference(TreeNode root) {
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode cur = root;//遍历的当前结点
        TreeNode pre = null;//前一个结点;
        while(cur != null || !deque.isEmpty()) {
            if(cur != null) {
                deque.push(cur);
                cur = cur.left;//左
            }else {
                TreeNode temp = deque.pop();//中
                if(pre != null) {
                    int difference = temp.val - pre.val;
                    if(difference < minResult) {
                        minResult = difference;
                    }
                }
                pre = temp;
                cur = temp.right;
            }
        }
        // getMin(root);
        return minResult;
    }

501.二叉搜索树中的众数

题目链接:501. 二叉搜索树中的众数 - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

思路:也把二叉搜索树当成有序数组进行处理,只需要对二叉树进行中序遍历

需要pre 和cur;pre是上一个结点,需要记录当前count频率,最大频率maxCount,结果集,如果更新最大频率,就清空结果集

    int count = 0;//统计频率;
    int maxCount = -10001; //最大频率;
    TreeNode pre = null;
    List<Integer> result = new ArrayList<>();

递归:

public void findMax(TreeNode node) {
    if(node == null)return;
    findMax(node.left);
    if(pre == null) count = 1;
    else if(pre.val == node.val) count ++;
    else count = 1;//与上一个不同

    if(count == maxCount) {
        result.add(node.val);
    }
    if(count > maxCount) {
        maxCount = count;
        result.clear();
        result.add(node.val);
    }
    pre = node;
    findMax(node.right);
}

迭代:  

    public int[] findMode(TreeNode root) {
        Deque<TreeNode> deque = new LinkedList<>();
        TreeNode cur = root;
        TreeNode pre = null;
        while(cur != null || !deque.isEmpty()) {
            if(cur != null) {
                deque.push(cur);
                cur = cur.left;
            }else {
                TreeNode node = deque.pop();
                if(pre == null) count = 1;
                else if(pre.val == node.val) count ++;
                else count = 1;

                if(count == maxCount) result.add(node.val);
                if(count > maxCount) {
                    result.clear();
                    maxCount = count;
                    result.add(node.val);
                }
                pre = node;
                cur = node.right;//右
            }
        }
        
        // findMax(root);
        int len = result.size();
        int[] res = new int[len];
        for(int i=0;i<len;i++) {
            res[i] = result.get(i);
        }
        return res;

        }

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

题目链接:​​​​​​​​​​​​​​. - 力扣(LeetCode)

文章讲解:代码随想录 (programmercarl.com)

 思路:最近公共祖先,右两种情况:

 

 我们想从底向上找公共祖先,用后序遍历即可实现,返回值可以为布尔表示是否找到公共祖先,题目中需要结点,所以返回结点,如果为p,q就返回,如果看到返回不为空就是找到p,q

图1:如果左孩子和右孩子返回都不为空,就返回root;

图2:如果有一个不为空就返回这个孩子结点;

递归:

  • 参数返回值:返回值为结点,参数为结点,p,q
  • 终止条件:如果结点为p,q,null就返回该结点
  • 单层逻辑:推给左右孩子找pq,处理他们的返回,(遍历整个树),都为空就返回空,都不为空就返回node,一个为空,一个不为空,就返回不为空的(走到这一步说明上一层没有触发终止条件;图2这种情况在递归到4时就返回了,不往下走了
    public TreeNode findCommon(TreeNode node, TreeNode p,TreeNode q) {
        if(node == q || node == p || node == null) return node;

        TreeNode left = findCommon(node.left,p,q);
        TreeNode right = findCommon(node.right,p,q);

        if(left != null && right != null) return node;
        if(left == null && right != null) return right;
        else if(left != null && right == null) return left;
        else return null;

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值