- Minimum Depth of Binary Tree
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
/**
* DFS思路,代码比较简洁,但如果是左侧500个单链孩子,右侧1个孩子这种比较极端的情况,时间复杂度会太高
* /
class Solution1 {
public int minDepth(TreeNode root) {
if(root==null){return 0;}
if(root.left==null && root.right==null){return 1;}
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;
}
}
/**
* BFS思路,faster than 100.00% 但是空间复杂度略高。
* 结论:一般来说在找最短路径的时候使用 BFS,其他时候还是 DFS 使用得多一些(主要是递归代码好写)
* /
class Solution2 {
public int minDepth(TreeNode root) {
if(root==null){return 0;}
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
int depth=1;
while(!q.isEmpty()){
int sz = q.size();
for(int i=0;i<sz;i++){
TreeNode current = q.poll();
if(current.left==null && current.right==null){return depth;}
if(current.left!=null){
q.add(current.left);
}
if(current.right!=null){
q.add(current.right);
}
}
depth++;
}
return 0;
}
}
- Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. Note: A leaf is a node with no children.
Example:
Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
/**
* DFS思路, 除去root是否满足条件的判断之外,重点在于看左右孩子中有没有满足sum-root.val的路径
* /
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if(root==null){return false;}
if(root.val==sum && root.left==null && root.right==null){return true;}
if(hasPathSum(root.left,sum-root.val)){return true;}
if(hasPathSum(root.right,sum-root.val)){return true;}
return false;
}
}
进阶版:
437. Binary Tree Paths
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
Example:
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
- 5 -> 3
- 5 -> 2 -> 1
- -3 -> 11
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);
}
private int dfs(TreeNode root,int sum){
int res=0;
if(root==null){return res;}
if(root.val==sum){res++;}
res+=dfs(root.left,sum-root.val);
res+=dfs(root.right,sum-root.val);
return res;
}
}
leetcode discussion: better solution using hash map
115. Invert Binary Tree
Example:
Input:
4
/ \
2 7
/ \ / \
1 3 6 9
Output:
4
/ \
7 2
/ \ / \
9 6 3 1
/**
* DFS递归思路,faster than 100.00% of Java online submissions for Invert Binary Tree.
*/
class Solution1 {
public TreeNode invertTree(TreeNode root) {
if(root==null){return null;}
TreeNode tmp = root.left;
root.left=root.right;
root.right=tmp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
/**
* BFS思路,复杂度比solution1更好些
*/
class Solution2 {
public TreeNode invertTree(TreeNode root) {
if(root==null){return null;}
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int sz = q.size();
for(int i=0;i<sz;i++){
TreeNode current = q.poll();
TreeNode tmp = current.left;
current.left = current.right;
current.right = tmp;
if(current.left!=null){q.offer(current.left);}
if(current.right!=null){q.offer(current.right);}
}
}
return root;
}
}
- Lowest Common Ancestor of a Binary Search Tree
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Example 1:
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null){return null;}
if(root==p || root==q){return root;}
if(root.val>Math.max(p.val,q.val)){
root = lowestCommonAncestor(root.left,p,q);
}else if(root.val< Math.min(p.val,q.val)){
root = lowestCommonAncestor(root.right,p,q);
}
return root;
}
}
- Binary Tree Paths 【重点看】
Example:
Input:
1
/ \
2 3
\
5
Output: [“1->2->5”, “1->3”]
Explanation: All root-to-leaf paths are: 1->2->5, 1->3
/**
* 好理解的DFS版本,String is immutable所以每次都会建立新的
* Runtime: 10 ms, Memory Usage: 40.5 MB
*/
class Solution1 {
public List<String> binaryTreePaths(TreeNode root) {
ArrayList<String> result = new ArrayList<>();
binaryTreePathsHelper(root,"",result);
return result;
}
private void binaryTreePathsHelper(TreeNode root, String solution, ArrayList<String> result){
if(root==null){return;}
if(root.left==null && root.right==null){result.add(solution+root.val);}
binaryTreePathsHelper(root.left,solution+root.val+"->",result);
binaryTreePathsHelper(root.right,solution+root.val+"->",result);
}
}
/**
* 改进版: We are passing object(address) of StringBuilder in recursion.
* StringBuilder is mutable- only one object(stringbuilder) would be created, so to avoid
* retaining the previous list of values, we set the length to restrict them to go over to the next level.
* Runtime: 1 ms, Memory Usage: 39.5 MB
*/
class Solution2 {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
StringBuilder sb= new StringBuilder();
helper(res,root,sb);
return res;
}
private void helper(List<String> res, TreeNode root, StringBuilder sb) {
if(root == null) {
return;
}
int len = sb.length();
sb.append(root.val);
if(root.left == null && root.right == null) {
res.add(sb.toString());
} else {
sb.append("->");
helper(res, root.left, sb);
helper(res, root.right, sb);
}
sb.setLength(len);
}
}
- Sum of Left Leaves
Find the sum of all left leaves in a given binary tree.
Example:
3
/ \
9 20
/ \
15 7
There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
class Solution {
public int sumOfLeftLeaves(TreeNode root) {
if(root==null){return 0;}
int sum = 0;
if(root.left!=null && root.left.left==null&& root.left.right==null){
sum+=root.left.val;
}
sum+=sumOfLeftLeaves(root.left);
sum+=sumOfLeftLeaves(root.right);
return sum;
}
}