代码随想录-2023/07/18

77 阅读2分钟

二叉树的应用

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

  1. 对于二叉搜索树而言, 中序遍历为升序, 所以最小绝对差出现在相邻的两个元素之间
  2. 递归中序遍历, 同时用前缀指针pre, 永远指向当前节点的上一个节点, 不断比较和记录最小绝对差, 同时更新前缀指针

代码:

class Solution {
    int min_diff = 0x7fffffff;
    TreeNode pre = null;
    public int getMinimumDifference(TreeNode root) {
        dfs(root);
        return min_diff;
    }
    public void dfs(TreeNode root){
        if(root == null) return;
        dfs(root.left);
        if(pre != null && root.val - pre.val < min_diff){
            min_diff = root.val - pre.val;
        }
        pre = root;
        dfs(root.right);
    }
}

501.二叉搜索树的众数

  1. 递归中序遍历二叉树, 同时用前缀指针指向上一个节点, 遍历的同时记录当前元素个数和最大个数
  2. 当前元素个数 > 最大元素个数: 清空结果集, 将当前节点加入结果集
  3. 当前元素个数 = 最大元素个数: 将当前节点值继续加入结果集

代码:

class Solution {
    List<Integer> list = new ArrayList<>();
    TreeNode pre = null;
    int cnt = 0, maxCnt = 0;
    public int[] findMode(TreeNode root) {
        dfs(root);
        return list.stream().mapToInt(x->x).toArray();
    }
    // 注意处理边界节点的情况
    public void dfs(TreeNode root) {
        if(root == null) return;
        dfs(root.left);

        // pre == null, root则代表是第一个节点
        if(pre == null) {
            cnt = 1;
        }else if(root.val == pre.val) {
            cnt++;   
        }else cnt = 1;

        if(cnt > maxCnt){
            // 清空结果集
            list.clear();
            list.add(root.val);
            // 更新最大cnt
            maxCnt = cnt;
        }else if(cnt == maxCnt){
            // 相同次数, 再装入结果集
            list.add(root.val);
        }
        // 更新指针指向
        pre = root;
        dfs(root.right);
    }
}

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

最近公共祖先求法: 对于一棵二叉树, 其中一个节点在其左子树上, 一个节点在其右子树上, 则当前节点为其最近公共祖先

  1. 需要知道子节点提供的信息, 所以需要后序遍历
  2. 子节点状态: 1: 代表找到目标节点 0: 代表只找到一个目标节点 -1: 代表未找到任何一个目标节点

代码:

class Solution {
    // 对于一棵二叉树, 其中一个节点在其左子树上, 一个节点在其右子树上
    // 则当前节点为其最近公共祖先
    TreeNode t = null;
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        dfs(root, p, q);
        return t;
    }
    // 当前节点的信息需要子节点提供:---需要后序遍历
    public int dfs(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return -1;
        int left = dfs(root.left, p, q);
        int right = dfs(root.right, p, q);
        // 1: 代表找到目标节点 0: 代表只找到一个目标节点 -1: 代表未找到任何一个目标节点
        if(left == 1 || right == 1) return 1;
        if(root == p || root == q) {
            if(left == 0 || right == 0){
                t = root;
                return 1;
            }else return 0;
        } else {
            if(left == 0 && right == 0) {
                t = root;
                return 1;
            }else if(left == 0 || right == 0){
                return 0;
            }else return -1;
        }
    }
}