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


文章目录

  • 530.二叉搜索树的最小绝对差
    • 1、代码(指针写法)
    • 2、分析
  • 501.二叉搜索树中的众数
    • 1、代码1
    • 2、代码2(指针写法)
    • 3、分析
  • 236. 二叉树的最近公共祖先
    • 1、代码
    • 2、分析


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

1、代码(指针写法)

/**
 * 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) {
        //二叉搜索树,中序遍历
        if(root == null) return 0;
        return dfs(root);
    }
    public int dfs(TreeNode node){
        if(node == null){
            return 0;
        }
        dfs(node.left);

        //中
        if(pre != null ){
            int cur = node.val - pre.val;
            result = Math.min(result,cur);
        }
        pre = node;

        dfs(node.right);
        return result;
    }
}

2、分析

(1)因为本题要求最小的值,所以全局变量初始化一个result变量用来接收最小绝对差。
(2)因为本题需要求两个节点之间的差值,所以需要初始化一个全局的节点变量用来记录上一个节点的值。

    TreeNode pre;

声明节点之后每次进行遍历时都要对其进行更新。

      pre = node;

所以在二叉树中需要用到指针的情况下我们可以声明一个全局变量的指针,并且在递归遍历时对其进行更新。

501.二叉搜索树中的众数

1、代码1

/**
 * 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 {
    public int[] findMode(TreeNode root) {
        //暴力解法
        //1、将二叉树信息封装为哈希map
        Map<Integer,Integer> map = new HashMap<>();
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list.stream().mapToInt(Integer::intValue).toArray();
        }
        dfs(root,map);

        //2、将哈希map进行排序
        List<Map.Entry<Integer,Integer>> mapList = map.entrySet().stream()
        .sorted((c1,c2) -> (c2.getValue().compareTo(c1.getValue())))
        .collect(Collectors.toList());
        list.add(mapList.get(0).getKey());
        //3、取出返回值中需要的值并返回
        for(int i=1; i<mapList.size(); i++){
            if(mapList.get(i).getValue() == mapList.get(i-1).getValue()){
                list.add(mapList.get(i).getKey());
            }else{
                break;
            }
        }
        return list.stream().mapToInt(Integer::intValue).toArray();
    }
    public void dfs(TreeNode node,Map<Integer,Integer> map){
        if(node == null) return;//
        map.put(node.val,map.getOrDefault(node.val,0) + 1);
        dfs(node.left,map);
        dfs(node.right,map);
    }
}

2、代码2(指针写法)

3、分析

(1)将线性表转化为数组的形式:

list.stream().mapToInt(Integer::intValue).toArray();

(2)将哈希map进行排序并将其封装为表的形式:

List<Map.Entry<Integer, Integer>> mapList = map.entrySet().stream()
		.sorted((c1, c2) -> c2.getValue().compareTo(c1.getValue()))
		.collect(Collectors.toList());

(3)由于本题中需要返回的是数组形式,而数组形式对于增减元素有一定难度,有一个技巧就是我们先建立一个线性表对元素进行操作,最后在返回的时候将线性表通过api直接转换为数组的形式。
(4)在写剪枝操作的时候始终要注意函数的返回值是什么类型。

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

1、代码

/**
 * 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) return null;
        if(root.val == p.val || root.val == q.val){
            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(right != null && left == null){
            return right;
        }else{
            return null;
        }
    }
}

2、分析

(1)本题由于是找二叉树的最近公共祖先,所以需要先验证子树是否符合情况,再根据子树的情况求出其祖先。由此我们可以知道需要用到回溯来判断祖先。再由于对于中间节点是否为公共祖先的判断我们需要需要借助左右子节点,所以我们在程序中需要用到后序遍历。
(2)由于需要用到子节点来判断祖先,所以我们要记录左右子节点的返回值用来判断祖先。
(3)当祖先找到左右节点时返回该祖先节点,并且通过回溯往上继续返回。当祖先只找到其中一个节点的时候,就返回找到的节点,通过带着找到的节点往上回溯直至找到共同的祖先节点。当找不到节点的时候都返回null。

你可能感兴趣的:(深度优先,算法)