LeetCode-问题1123-最深叶节点的最近公共祖先

题目链接

https://leetcode.cn/problems/lowest-common-ancestor-of-deepest-leaves/

解答过程

这个题目乍一看有点迷糊,但结合示例稍加分析,可以明白题目的含义。一颗二叉树,每个节点都有一个depth,根节点depth为0,每往下每一层depth加1。这些节点中有一些是叶子节点,即没有孩子的节点。这些叶子节点可能有不同的depth,我们把depth最大的那些叶子节点挑出来,问题来了,这些被挑选出来的depth最大的叶子节点,它们的最小公共祖先是哪个节点?

解题思路嘛,第一直觉就是按上面的描述把这些depth最大的叶子节点找出来,这个处理还是比较简单的,层级遍历嘛,最后遍历到的那一层就是depth最大的叶子节点。那么如何确定这些叶子节点的最小公共祖先呢?想到的笨办法就是把每个节点的父节点信息维护起来,这样对于给定的一组节点,连续往上查找父节点,直到所有节点相等,那么我们就得到了最小公共祖先。

	public TreeNode lcaDeepestLeaves(TreeNode root) {
		if (root == null) {
			return null;
		}

		Map<TreeNode, TreeNode> parents = new HashMap<>();
		parents.put(root, null);

		List<TreeNode> list = new ArrayList<>();

		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(root);
		while (!queue.isEmpty()) {
			list.clear();

			int size = queue.size();
			while (size-- > 0) {
				TreeNode node = queue.poll();

				list.add(node);

				if (node.left != null) {
					queue.offer(node.left);
					parents.put(node.left, node);
				}
				if (node.right != null) {
					queue.offer(node.right);
					parents.put(node.right, node);
				}
			}
		}

		if (list.size() == 1) {
			return list.get(0);
		}

		while (true) {
			if (allSame(list)) {
				return list.get(0);
			}

			list.replaceAll(parents::get);
		}
	}

	private boolean allSame(List<TreeNode> list) {
		TreeNode first = list.get(0);
		for (TreeNode node : list) {
			if (node != first) {
				return false;
			}
		}

		return true;
	}

代码提交以后是没有问题的,效率较差,但思路很好理解。看了一下官方题解,有点意思,确实思路更显高级,代码也更简洁。参考递归思路又写了下:

	public TreeNode lcaDeepestLeaves(TreeNode root) {
		Object[] ret = recur(root);
		return (TreeNode) ret[1];
	}

	private Object[] recur(TreeNode node) {
		if (node == null) {
			return new Object[] {0, null};
		}

		Object[] left = recur(node.left);
		Object[] right = recur(node.right);

		int leftDepth = (int) left[0];
		TreeNode leftLca = (TreeNode) left[1];
		int rightDepth = (int) right[0];
		TreeNode rightLca = (TreeNode) right[1];
		if (leftDepth > rightDepth) {
			return new Object[] {leftDepth + 1, leftLca};
		} else if (leftDepth < rightDepth) {
			return new Object[] {rightDepth + 1, rightLca};
		} else {
			return new Object[] {leftDepth + 1, node};
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值