6、二叉树和递归
1、二叉树天然的递归结构
public int maxDepth(TreeNode root) {
if (root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
更多问题
111 - 二叉树的最小深度
2、一个简单的二叉树问题引发的血案
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
TreeNode l = invertTree(root.left);
TreeNode r = invertTree(root.right);
root.left = r;
root.right = l;
return root;
}
// 完全二叉树的节点个数
public int countNodes(TreeNode root) {
if (root == null) return 0;
int lefDepth = lefDepth(root);
int rightDepth = rightDepth(root);
if (lefDepth == rightDepth) return (int) (Math.pow(2, lefDepth) - 1);
else return countNodes(root.left) + countNodes(root.right) + 1;
}
public int lefDepth(TreeNode node) {
if (node == null) return 0;
return lefDepth(node.left) + 1;
}
public int rightDepth(TreeNode node) {
if (node == null) return 0;
return rightDepth(node.right) + 1;
}
3、注意递归的终止条件
// 错误的代码
public boolean hasPathSum1(TreeNode root, int targetSum) {
if (root == null) return true;
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
// 正确的代码
public boolean hasPathSum2(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) return targetSum == root.val; // 叶子节点
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}
更多问题
404 - 左叶子之和
4、定义递归问题
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
if (root == null) return res;
if (root.left == null && root.right == null) {
res.add("" + root.val);
return res;
}
for (String s : binaryTreePaths(root.left)) res.add(root.val + "->" + s);
for (String s : binaryTreePaths(root.right)) res.add(root.val + "->" + s);
return res;
}
5、稍复杂的递归逻辑
// 在以 root 为根节点的二叉树中, 寻找和为 sum 的路径, 返回路径个数
public static int pathSum(TreeNode root, int sum) {
if (root == null) return 0;
int res = findPath(root, sum); // 包含当前 root 节点, 和为 sum 的路径
res += pathSum(root.left, sum); // 不包含当前 root 节点, 和为 sum 的路径
res += pathSum(root.right, sum); // 不包含当前 root 节点, 和为 sum 的路径
return res;
}
// 在以 node 为根节点的二叉树中, 寻找包含 node 的和为 sum 的路径, 返回路径个数
private static int findPath(TreeNode node, long sum) {
if (node == null) return 0;
int res = 0;
if (node.val == sum) res++;
res += findPath(node.left, sum - node.val);
res += findPath(node.right, sum - node.val);
return res;
}
6、二分搜索树中的问题
// 只要 p 和 q 不在 root 的同侧, 那么 root 就是最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (p.val < root.val && q.val < root.val) return lowestCommonAncestor(root.left, p, q);
if (p.val > root.val && q.val > root.val) return lowestCommonAncestor(root.right, p, q);
return root;
}
更多问题
98 - 验证二叉搜索树
450 - 删除二叉搜索树中的节点
108 - 将有序数组转换为二叉搜索树
230 - 二叉搜索树中第 K 小的元素
236 - 二叉树的最近公共祖先
本文来自博客园,作者:lidongdongdong~,转载请注明原文链接:https://www.cnblogs.com/lidong422339/p/17406647.html