104. Maximum Depth of Binary Tree
找到二叉树的最大深度。
public class Solution { public int maxDepth(TreeNode root) { if (root == null) { return 0; } int l = maxDepth(root.left) + 1; int r = maxDepth(root.right) + 1; return l > r ? l : r; } }
111. Minimum Depth of Binary Tree
找到二叉树的最小深度
思路:与最大深度不同的地方在于,若一个节点只有左节点或者右节点的其中之一的节点,则该节点并不为完整路径的叶节点,一定要找到叶节点才能判断最小路径
public class Solution { public int minDepth(TreeNode root) { if (root == null) { return 0; } if (root.left == null) { return minDepth(root.right) + 1; } if (root.right == null) { return minDepth(root.left) + 1; } return Math.min(minDepth(root.left), minDepth(root.right)) + 1; } }
112. Path Sum
给定一个树和一个整数,决定是否该树有从跟节点到叶节点的一条路径上的值的和等于给定的这个整数
思路:前序遍历,若没有左右子节点的话,判断当前根节点是否等于sum,若不等于,sum减去当前根节点的值,继续向下遍历。
public class Solution { public boolean hasPathSum(TreeNode root, int sum) { if (root == null) { return false; } if (root.left == null && root.right == null && sum == root.val) { return true; } return (hasPathSum(root.left, sum-root.val) || hasPathSum(root.right, sum-root.val)); } }
113. Path Sum II
给定一个树和一个整数,找到所有从根节点到叶节点的路径上的值的和等于给的这个整数,要返回下面这种。
[ [5,4,11,2], [5,8,4,5] ]
思路:与上一题不同之处在于,上一题是判断存不存在,该题要找到所有符合的路径,两个list是必不可少。内层list来存储符合的路径。然后遍历到叶节点符合条件,就将对应的一条路径添加到外层list中,这里有两个关键点,前序遍历是必不可少,问题是遍历的过程中如果访问到某一叶节点,但这条路径不符合。那么内层list需要一个一个remove掉当前元素,即使该路径符合,为了寻找新的符合条件路径,也需要remove掉当前的值。所以在遍历的最后要remove掉当前节点的值。
易错的地方:因为innerlist是处于一直增删的状态。所以确定了某一完整的符合条件的路径后,应新建一个temp的list来存储对应的innerlist,但不能直接把引用=innerlist,这样两者的地址会一样。所以方法是将innerlist的值复制到temp中,所以应该用 addAll方法来处理。
public class Solution { List<List<Integer>> list = new ArrayList<>(); List<Integer> innerlist = new ArrayList<>(); public List<List<Integer>> pathSum(TreeNode root, int sum) { if (root == null) { return list; } innerlist.add(root.val); hasPathSum(root, sum - root.val); return list; } public void hasPathSum(TreeNode root, int sum) { if (root.left == null && root.right == null && sum == 0) { List<Integer> temp = new ArrayList<>(); temp.addAll(innerlist); list.add(temp); } if (root.left != null) { innerlist.add(root.left.val); hasPathSum(root.left, sum - root.left.val); innerlist.remove(innerlist.size() - 1); } if (root.right != null) { innerlist.add(root.right.val); hasPathSum(root.right, sum - root.right.val); innerlist.remove(innerlist.size() - 1); } } }
437. Path Sum III
给定一个树和一个整数,找到所有从任意节点到任意节点的路径上的值的和等于给的这个整数,但一定是从上到下的逻辑顺序。返回共有多少条路径。
思路:与前两题不一样的地方在于 不是从根节点开始了,而是从任意节点开始到下面节点路径和为该值即可。很典型的动态规划的问题。先考虑跟节点去往下遍历,记录从根节点开始的符合情况,接着从根节点的左右子节点开始遍历。
public class Solution { public int pathSum(TreeNode root, int sum) { if (root == null) { return 0; } return dfs(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); } public int dfs(TreeNode root, int sum) { int res = 0; if (root == null) { return 0; } if (root.val == sum) { ++res; } res += dfs(root.left, sum - root.val); res += dfs(root.right, sum - root.val); return res; } }
102. Binary Tree Level Order Traversal 待修改,减少空间复杂度
给定一个二叉树,从左到右,一层一层返回遍历的值。类似下面这种
3 / 9 20 / 15 7
return its level order traversal as:
[ [3], [9,20], [15,7] ] 思路:利用两个双端队列linkedlist去存储当前遍历的层以及下一层要遍历的元素,通过remove将队列中的节点一个一个处理。
public class Solution { public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> list = new ArrayList<List<Integer>>(); ArrayList<Integer> nodeValue = new ArrayList<Integer>(); if (root == null){ return list; } LinkedList<TreeNode> current = new LinkedList<TreeNode>(); LinkedList<TreeNode> next = new LinkedList<TreeNode>(); current.add(root); while (!current.isEmpty()) { TreeNode node = current.remove(); if (node.left != null) { next.add(node.left); } if (node.right != null) { next.add(node.right); } nodeValue.add(node.val); if (current.isEmpty()) { current = next; next = new LinkedList<TreeNode>(); list.add(nodeValue); nodeValue = new ArrayList<Integer>(); } } return list; } }
107. Binary Tree Level Order Traversal II 待修改,减少空间复杂度
与上题不同之处在于要倒序输出,返回如下这种
[ [15,7], [9,20], [3] ]思路:最后对上一题的list进行reverse即可。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public List<List<Integer>> levelOrderBottom(TreeNode root) { List<List<Integer>> list = new ArrayList<List<Integer>>(); List<Integer> nodeValue = new ArrayList<Integer>(); if (root == null){ return list; } LinkedList<TreeNode> current = new LinkedList<TreeNode>(); LinkedList<TreeNode> next = new LinkedList<TreeNode>(); current.add(root); while (!current.isEmpty()){ TreeNode node = current.remove(); if (node.left != null){ next.add(node.left); } if (node.right != null){ next.add(node.right); } nodeValue.add(node.val); if (current.isEmpty()){ current = next; next = new LinkedList<TreeNode>(); list.add(nodeValue); nodeValue = new ArrayList<Integer>(); } } Collections.reverse(list);return reverseList; } }
100. Same Tree
给两个二叉树,判断这个两个二叉树是不是相同的,如果他们结构一致,且节点值相同,则为相同
思路:该题不难,遍历对应的节点值是否相等即可。
public class Solution { public boolean isSameTree(TreeNode p, TreeNode q) { if (p == null && q == null) { return true; } if (p == null || q == null) { return false; } if (p.val != q.val) { return false; } return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); } }