代码随想录算法训练营day21

Day21

二叉搜索树的最小绝对差

https://leetcode.cn/problems/minimum-absolute-difference-in-bst/

题目

给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cARYIJob-1688576336197)(https://note.youdao.com/yws/res/89359/WEBRESOURCE2797fec86128d95da0e697d6ef80256c)]

思路

题目中要求在二叉搜索树上任意两节点的差的绝对值的最小值。

注意是二叉搜索树,二叉搜索树可是有序的。

遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。

代码

中序遍历
class Solution {
    private int min = Integer.MAX_VALUE;
    private List<Integer> numList = new ArrayList<>();
    public int getMinimumDifference(TreeNode root) {
        traversal(root);
        for(int i = 1; i < numList.size(); i++){
            min = Math.min(min, Math.abs(numList.get(i) - numList.get(i - 1)));
        }
        return min;
    }

    private void traversal(TreeNode root){
        if(root == null) return;
        traversal(root.left); // 左
        numList.add(root.val);// 中
        traversal(root.right);// 右
    }
}
递归中处理
class Solution {
    private int min = Integer.MAX_VALUE;
    TreeNode node = null;
    public int getMinimumDifference(TreeNode root) {
        traversal(root);
        return min;
    }

    private void traversal(TreeNode root){
        if(root == null) return;
        traversal(root.left); // 左
        if(node != null){
            min = Math.min(min, Math.abs(root.val - node.val));
        }
        node = root;    // 保存上一个节点
        traversal(root.right);// 右
    }
}
迭代法-中序遍历
class Solution {
   
    public int getMinimumDifference(TreeNode root) {
        int min = Integer.MAX_VALUE;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        TreeNode pre = null;
        while(cur != null || !stack.isEmpty()){
            if(cur != null){
                stack.push(cur);
                cur = cur.left; // 左
            }else{
                cur = stack.pop();
                if(pre != null){
                    min = Math.min(min, Math.abs(pre.val - cur.val));  // 中
                }
                pre = cur;
                cur = cur.right; // 右
            }
        }
        return min;
    }
}

二叉搜索树中的众数

https://leetcode.cn/problems/find-mode-in-binary-search-tree/

题目

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:

给定 BST [1,null,2,2],

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q5bK3Loe-1688576336198)(https://note.youdao.com/yws/res/89374/WEBRESOURCE81e59cccc49e95957ae95c84af5fc658)]

  1. 二叉搜索树中的众数

返回[2].

提示:如果众数超过1个,不需考虑输出顺序

思路

代码

普通方法
class Solution {
    public int[] findMode(TreeNode root) {
		Map<Integer, Integer> map = new HashMap<>();
		List<Integer> list = new ArrayList<>();
		if (root == null) return list.stream().mapToInt(Integer::intValue).toArray();
		// 获得频率 Map
		searchBST(root, 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());
		// 把频率最高的加入 list
		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();
	}

	void searchBST(TreeNode curr, Map<Integer, Integer> map) {
		if (curr == null) return;
		map.put(curr.val, map.getOrDefault(curr.val, 0) + 1);
		searchBST(curr.left, map);
		searchBST(curr.right, map);
	}
}
用二叉搜索树特性

既然是搜索树,它中序遍历就是有序的。

class Solution {
    List<Integer> res = new ArrayList<>();
    Integer maxCount = 0;
    Integer count = 0;
    TreeNode pre = null;

    public int[] findMode(TreeNode root) {
        traversal(root);
        int nums[] = new int[res.size()];
        for (int i = 0; i < res.size(); i++) {
            nums[i] = res.get(i);
        }
        return nums;
    }

    public void traversal(TreeNode root){
        if(root == null) return;
        traversal(root.left);   // 左

        // 中
        if (pre == null || pre.val != root.val){
            count = 1;
        } else {
            count++;
        }

        if (count == maxCount){
            res.add(root.val);
        } else if (count > maxCount){
            res.clear();
            res.add(root.val);
            maxCount = count;
        }
        pre = root;
        
        traversal(root.right);  // 右
    }
}

二叉树的最近公共祖先

https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/

题目

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树:  root = [3,5,1,6,2,0,8,null,null,7,4]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KXDkRdOy-1688576336198)(https://code-thinking-1253855093.file.myqcloud.com/pics/20201016173414722.png “236. 二叉树的最近公共祖先”)]

示例 1: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出: 3 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。

示例 2: 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出: 5 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。

说明:

  • 所有节点的值都是唯一的。
  • p、q 为不同节点且均存在于给定的二叉树中。

思路

代码随想录 (programmercarl.com)

这里是从底向上进行遍历,后序遍历(天然支持回溯)

代码

class Solution {
    // 后序遍历(天然支持回溯)
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == p || root == q || root == null) 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(left == null && right != null) return right;
        else return null; // (left == NULL && right == NULL)
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值