Leetcode题目-110. Balanced Binary Tree
思路
本题中,高度平衡(height-balanced):一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。
高度是指当前节点到叶子结点的距离。所以要衡量当前节点是否平衡,要先获取到当前节点的左右子树的高度后,再进行比较。依照这个逻辑,可以想到使用的是后序遍历(查完左右后回到中)。后序遍历思路依然可以使用递归来解决。
- 确定递归函数:
private int getHeight(TreeNode root)
因为此题中,子树为平衡二叉树并不代表当前节点也是平衡二叉树,所以我们需要分别获取子树的高度,来比较,且当前节点的高度是子树的最大高度+1,所以我们的递归函数选取为获取当前节点高度。 - 递归终止条件:
if (root==null) { return 0; }
当遍历到空结点时,空节点的高度为0。 - 单次递归逻辑:分别计算当前节点的左右子树高度,进行比较后,如果高度差的绝对值超过1,则不是平衡二叉树(可以通过一个);如果不超过,当前节点的高度为左右子树最大值+1,然后返回上一层进行继续比较,直到回溯到根节点。
代码实现
class Solution {
public boolean isBalanced(TreeNode root) {
return getHeight(root) != -1;
}
private int getHeight(TreeNode root) {
if (root == null) {
return 0;
}
int leftHeight = getHeight(root.left);
if (leftHeight == -1 ) {
return -1;
}
int rightHeight = getHeight(root.right);
if (rightHeight == -1) {
return -1;
}
if (Math.abs(leftHeight - rightHeight) > 1) {
return -1;
}else {
return Math.max(leftHeight, rightHeight) + 1;
}
}
}
总结
这里主要是要理解到后序遍历中,获取到左右子树的节点后,也将自己的高度回溯到上层中这一过程。同时注意二叉树的高度与深度的区别。(根节点的高度就是二叉树的深度)。
Leetcode题目-257. Binary Tree Paths
思路
这题需要记录所有根节点到叶子结点的路径。这里考虑前序遍历,因为要先获取到根节点后,再通过其指向它的左右子节点。但因为此题需要遍历所有的路径,所以这里涉及到回溯,完成一条路径后,需要回溯到上一节点,从而进行下一条路径的遍历。
使用递归解决:
- 确定递归函数:
private void getPath(TreeNode root, String path, List<String> result)
- 递归终止条件:
if (root == null) { result.add(path); }
当递归到空节点时,完成一条路径的遍历,并添加到结果集中。 - 单层递归逻辑:将当前节点衔接到到path路径中,并接下去遍历当前节点的左右子节点,并注意递归后的回溯。
代码实现
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
String path = "";
List<String> result = new ArrayList<>();
getPath(root, path, result);
return result;
}
private void getPath(TreeNode root, String path, List<String> result) {
path = path + root.val;
if (root.left ==null && root.right == null) {
result.add(path);
return;
}
if (root.left != null) {
getPath(root.left, path + "->", result);
}
if (root.right != null) {
getPath(root.right, path + "->", result);
}
}
}
总结
注意隐藏的回溯逻辑,这里才传参的时候使用path + “->”,而非用path直接传参,所以隐式地隐藏了回溯。
Leetcode题目-404. Sum of Left Leaves
思路
要找左叶子,首先需要是一个叶子结点(左右节点为空),同时它还是某个节点的左节点。这里使用后序遍历,因为获取到左右子节点后需要将获取到的结果累加到父节点,最后到根节点,就能获取到整棵树的结果总和。
- 确定递归函数:
public int sumOfLeftLeaves(TreeNode root)
- 递归终止条件:
if (root == null) return 0;
- 单层递归逻辑:判断当前节点的左右节点是否为叶子结点,如是,则累加到总和中。
代码实现
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) {
return 0;
}
if (root.left == null && root.right == null) {
return 0;
}
int sum = 0;
if (root.left != null && root.left.left == null && root.left.right == null) {
sum += root.left.val;
}
return sum + sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right);
}
}
总结
这里对遍历顺序的原理理解比较重要,因为要处理返回值,所以最后结果需要最后回收,采用后序来实现。