leetcode树习题
104:二叉树的深度
递归并借用数学函数解决
public int maxDepth(TreeNode root) {
if (root == null) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
110:平衡树
private boolean result = true;
public boolean isBalanced(TreeNode root) {
maxDepth(root);
return result;
}
public int maxDepth(TreeNode root) {
if (root == null) return 0;
int l = maxDepth(root.left);
int r = maxDepth(root.right);
if (Math.abs(l - r) > 1) result = false;
return 1 + Math.max(l, r);
}
543:二叉树的直径
理解直径的概念
private int max = 0;
public int diameterOfBinaryTree(TreeNode root) {
depth(root);
return max;
}
private int depth(TreeNode root) {
if (root == null) return 0;
int l = depth(root.left);
int r = depth(root.right);
max = Math.max(max, l + r);
return Math.max(l, r) + 1;
}
226:翻转树
递归思想
public TreeNode invertTree(TreeNode root) {
if(root==null) return root;
TreeNode left=root.left;
TreeNode right=root.right;
root.left=invertTree(right);
root.right=invertTree(left);
return root;
}
617:归并两棵树
递归思想
public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return null;
if (t1 == null) return t2;
if (t2 == null) return t1;
TreeNode root = new TreeNode(t1.val + t2.val);
root.left = mergeTrees(t1.left, t2.left);
root.right = mergeTrees(t1.right, t2.right);
return root;
}
112:判断路径和是否等于一个数
递归
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) return false;
if (root.left == null && root.right == null && root.val == sum) return true;
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
对于递归过程中是否需要记录变量值,不是很清楚,需要继续总结摸索。
437:统计路径满足某数的数量
如何完成遍历,双递归操作
public int pathSum(TreeNode root, int sum) {
if (root == null) return 0;
int ret = pathSumStartWithRoot(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
return ret;
}
private int pathSumStartWithRoot(TreeNode root, int sum) {
if (root == null) return 0;
int ret = 0;
if (root.val == sum) ret++;
ret += pathSumStartWithRoot(root.left, sum - root.val) + pathSumStartWithRoot(root.right, sum - root.val);
return ret;
}
572:子树
和寻找路径数思路相同
注意题干中要求是非空子树
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isSymmetric(root.left, root.right);
}
private boolean isSymmetric(TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return true;
if (t1 == null || t2 == null) return false;
if (t1.val != t2.val) return false;
return isSymmetric(t1.left, t2.right) && isSymmetric(t1.right, t2.left);
}
111:最小路径问题
注意没有左右子树的情况
public int minDepth(TreeNode root) {
if (root == null) return 0;
int left = minDepth(root.left);
int right = minDepth(root.right);
if (left == 0 || right == 0) return left + right + 1;
return Math.min(left, right) + 1;
}
404:统计左叶子节点的和
判断左侧是否为叶子节点,找到左侧的叶子节点为结束标志
叶子节点的判断是关键
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) return 0;
if (isLeaf(root.left)) return root.left.val + sumOfLeftLeaves(root.right);
return sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right);
}
private boolean isLeaf(TreeNode node){
if (node == null) return false;
return node.left == null && node.right == null;
}
687:相同节点值的最大路径长度
递归还是解决问题的难点
区分开,记录值和输出贡献值
private int path = 0;
public int longestUnivaluePath(TreeNode root) {
dfs(root);
return path;
}
private int dfs(TreeNode root){
if (root == null) return 0;
int left = dfs(root.left);
int right = dfs(root.right);
int leftPath = root.left != null && root.left.val == root.val ? left + 1 : 0;
int rightPath = root.right != null && root.right.val == root.val ? right + 1 : 0;
path = Math.max(path, leftPath + rightPath);
return Math.max(leftPath, rightPath);
337:间隔遍历
理解题意是关键,间隔一层才能取得最大的收益为什么呢?
public int rob(TreeNode root) {
if (root == null) return 0;
int val1 = root.val;
if (root.left != null) val1 += rob(root.left.left) + rob(root.left.right);
if (root.right != null) val1 += rob(root.right.left) + rob(root.right.right);
int val2 = rob(root.left) + rob(root.right);
return Math.max(val1, val2);
}
671:寻找二叉树中第二小的元素
方法讲解
由条件可知,根节点一定是最小的,其余的父节点也是小于子节点,分别找到根节点的左右子树中第一次不与根节点相等的节点,两者中较小的即是第二小的。