@Yano
2019-09-20T10:51:52.000000Z
字数 34071
阅读 6305
LeetCode
https://www.zybuluo.com/Yano/note/1009816
https://leetcode.com/problems/binary-tree-inorder-traversal/
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree [1,null,2,3],
1
\
2
/
3
return [1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
robot(root, ans);
return ans;
}
private void robot(TreeNode root, List<Integer> ans) {
if(root == null) return;
robot(root.left, ans);
ans.add(root.val);
robot(root.right, ans);
}
public class Solution {
public List<Integer> inorderTraversal(TreeNode r) {
List<Integer> ans = new ArrayList<Integer>();
List<TreeNode> vector = new ArrayList<TreeNode>();
while(vector.size() != 0 || r != null){
// 一直放入左儿子(左)
while(r != null) {
vector.add(r);
r = r.left;
}
// 访问当前元素(中),把右儿子入栈(右)
if(vector.size() != 0) {
r = vector.get(vector.size() - 1);
vector.remove(vector.size() - 1);
ans.add(r.val);
r = r.right;
}
}
return ans;
}
}
https://leetcode.com/problems/binary-tree-preorder-traversal/
Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree [1,null,2,3],
1
\
2
/
3
return [1,2,3].
Note: Recursive solution is trivial, could you do it iteratively?
public class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<Integer>();
List<TreeNode> vector = new ArrayList<TreeNode>();
vector.add(root);
while(vector.size() != 0) {
TreeNode tmp = vector.get(vector.size() - 1);
vector.remove(vector.size() - 1);
if(tmp != null) {
ans.add(tmp.val);
vector.add(tmp.right);
vector.add(tmp.left);
}
}
return ans;
}
}
https://leetcode.com/problems/binary-tree-postorder-traversal/
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3},
1
\
2
/
3
return [3,2,1].
Note: Recursive solution is trivial, could you do it iteratively?
public class Solution {
public static class StackNode {
TreeNode root;
boolean visit;
StackNode(TreeNode root) {
this.root = root;
}
}
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<Integer>();
if(root == null) return ans;
List<StackNode> vector = new ArrayList<StackNode>();
StackNode node;
vector.add(new StackNode(root));
while(vector.size() != 0) {
node = vector.get(vector.size() - 1);
vector.remove(vector.size() - 1);
if(node != null) {
if(!node.visit) {
node.visit = true;
vector.add(node);
if(node.root.right != null) vector.add(new StackNode(node.root.right));
if(node.root.left != null) vector.add(new StackNode(node.root.left));
} else if(node.root != null){
ans.add(node.root.val);
}
}
}
return ans;
}
}
https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
return its zigzag level order traversal as:
[
[3],
[20,9],
[15,7]
]
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
robot(root, 0, ans);
for(int i = 0; i < ans.size(); i++) {
if(i % 2 != 0) {
Collections.reverse(ans.get(i));
}
}
return ans;
}
private void robot(TreeNode root, int level, List<List<Integer>> ans) {
if(root == null) return;
if(ans.size() <= level) {
ans.add(new ArrayList());
}
ans.get(level).add(root.val);
robot(root.left, level + 1, ans);
robot(root.right, level + 1, ans);
}
}
https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
class Solution {
public TreeNode buildTree(int[] pre, int[] in) {
return robot(pre, in, 0, 0, in.length - 1);
}
private TreeNode robot(int[] pre, int[] in, int preStart, int inStart, int inEnd) {
if(preStart >= pre.length || inStart > inEnd) return null;
// 找到pos
TreeNode root = new TreeNode(pre[preStart]);
int index = 0;
for(int i = inStart; i <= inEnd; i++) {
if(in[i] == root.val) {
index = i;
break;
}
}
root.left = robot(pre, in, preStart + 1, inStart, index - 1);
root.right = robot(pre, in, preStart + 1 + index - inStart, index + 1, inEnd);
return root;
}
}
https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
class Solution {
public TreeNode buildTree(int[] in, int[] post) {
return robot(in, post, 0, in.length - 1, 0, post.length - 1);
}
private TreeNode robot(int[] in, int[] post, int inStart, int inEnd, int postStart, int postEnd) {
if(postStart > postEnd) return null;
TreeNode root = new TreeNode(post[postEnd]);
int pos = 0;// 找到pos
for(int i = inStart; i <= inEnd; i++) {
if(in[i] == root.val) {
pos = i;
break;
}
}
root.left = robot(in, post, inStart, pos - 1, postStart, postStart + pos - inStart - 1);
root.right = robot(in, post, pos + 1, inEnd, postEnd + pos - inEnd, postEnd - 1);
return root;
}
}
https://leetcode.com/problems/unique-binary-search-trees/
Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
public int numTrees(int n) {
int[] ans = new int[n + 2];
ans[0] = 1; ans[1] = 1; ans[2] = 2;
// f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ……
for(int i = 3; i <= n; i++) {
for(int j = 0; j <= i - 1; j++) {
ans[i] += ans[j] * ans[i - j - 1];
}
}
return ans[n];
}
https://leetcode.com/problems/unique-binary-search-trees-ii/
Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n.
For example,
Given n = 3, your program should return all 5 unique BST's shown below.
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
class Solution {
public List<TreeNode> generateTrees(int n) {
if(n <= 0) return new ArrayList<>();
return build(1, n);
}
private List<TreeNode> build(int start, int end) {
List<TreeNode> roots = new ArrayList<>();
if(start > end) {
// null也要放入,否则下面的双重循环进不去
roots.add(null);
return roots;
}
if(start == end) {
roots.add(new TreeNode(start));
return roots;
}
for(int i = start; i <= end; i++) {
List<TreeNode> leftList = build(start, i - 1);
List<TreeNode> rightList = build(i + 1, end);
for(TreeNode left : leftList) {
for(TreeNode right : rightList) {
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
roots.add(root);
}
}
}
return roots;
}
}
https://leetcode.com/problems/validate-binary-search-tree/
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
Example 1:
2
/ \
1 3
Binary tree [2,1,3], return true.
Example 2:
1
/ \
2 3
Binary tree [1,2,3], return false.
public boolean isValidBST(TreeNode root) {
// 用long型
return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
private boolean isValidBST(TreeNode root, long min, long max) {
if(root == null) return true;
if(root.val >= max || root.val <= min) return false;
return isValidBST(root.left, min, root.val) && isValidBST(root.right, root.val, max);
}
https://leetcode.com/problems/recover-binary-search-tree/
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
class Solution {
TreeNode first = null, second = null;
TreeNode pre = new TreeNode(Integer.MIN_VALUE);
public void recoverTree(TreeNode root) {
if(root == null) return;
robot(root);
if(first != null && second != null) {
int tmp = first.val;
first.val = second.val;
second.val = tmp;
}
}
private void robot(TreeNode root) {
if(root == null) return;
robot(root.left);
// 找到交换的两个节点
if(first == null && pre.val >= root.val) {
first = pre;
}
if(first != null && pre.val >= root.val) {
second = root;
}
pre = root;
robot(root.right);
}
}
https://leetcode.com/problems/delete-node-in-a-bst/
Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.
Basically, the deletion can be divided into two stages:
Search for a node to remove.
If the node is found, delete the node.
Note: Time complexity should be O(height of tree).
Example:
root = [5,3,6,2,4,null,7]
key = 3
5
/ \
3 6
/ \ \
2 4 7
Given key to delete is 3. So we find the node with value 3 and delete it.
One valid answer is [5,4,6,2,null,null,7], shown in the following BST.
5
/ \
4 6
/ \
2 7
Another valid answer is [5,2,6,null,4,null,7].
5
/ \
2 6
\ \
4 7
class Solution {
TreeNode target = null;
TreeNode targetParent = null;
public TreeNode deleteNode(TreeNode root, int key) {
// 1. 找到目标节点
find(root, key);
if(target == null) return root;
// 2. update
if(target == root) {
if(target.left == null && target.right == null) return null;
targetParent = target.left == null ? target.right : target.left;
if(target.left != null) {
getMaxNode(targetParent).right = target.right;
} else {
// target.right = null;
}
return targetParent;
}
if(target.left != null) {
getMaxNode(target.left).right = target.right;
adjust(targetParent, target, target.left);
} else if(target.right != null) {
adjust(targetParent, target, target.right);
} else {
adjust(targetParent, target, null);
}
return root;
}
private void adjust(TreeNode targetParent, TreeNode target, TreeNode replace) {
if(targetParent.left == target) targetParent.left = replace;
if(targetParent.right == target) targetParent.right = replace;
}
private TreeNode getMaxNode(TreeNode root) {
if(root == null) return null;
while(root.right != null) {
root = root.right;
}
return root;
}
private void find(TreeNode root, int key) {
if(root == null) return;
if(root.left != null && root.left.val == key) {
targetParent = root;
}
if(root.right != null && root.right.val == key) {
targetParent = root;
}
if(root.val == key) {
target = root;
return;
}
find(root.left, key);
find(root.right, key);
}
}
https://leetcode.com/problems/kth-smallest-element-in-a-bst/
Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.
Note:
You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
Credits:Special thanks to @ts for adding this problem and creating all test cases.
class Solution {
int ans = 0;
int count = 0;
public int kthSmallest(TreeNode root, int k) {
count = k;
robot(root);
return ans;
}
private void robot(TreeNode root) {
if(root == null) return;
robot(root.left);
if(--count == 0) {
ans = root.val;
return;
}
robot(root.right);
}
}
https://leetcode.com/problems/same-tree/
Given two binary trees, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical and the nodes have the same value.
Example 1:
Input: 1 1
/ \ / \
2 3 2 3
[1,2,3], [1,2,3]
Output: true
Example 2:
Input: 1 1
/ \
2 2
[1,2], [1,null,2]
Output: false
Example 3:
Input: 1 1
/ \ / \
2 1 1 2
[1,2,1], [1,1,2]
Output: false
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);
}
}
https://leetcode.com/problems/symmetric-tree/
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree [1,2,2,3,4,4,3] is symmetric:
1
/ \
2 2
/ \ / \
3 4 4 3
But the following [1,2,2,null,3,null,3] is not:
1
/ \
2 2
\ \
3 3
Note:
Bonus points if you could solve it both recursively and iteratively.
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root == null) return true;
return isSymmetric(root.left, root.right);
}
private boolean isSymmetric(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 isSymmetric(p.left, q.right) && isSymmetric(p.right, q.left);
}
}
https://leetcode.com/problems/binary-tree-level-order-traversal/
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).
For example:
Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
return its level order traversal as:
[
[3],
[9,20],
[15,7]
]
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
robot(root, 0, ans);
return ans;
}
private void robot(TreeNode root, int level, List<List<Integer>> ans) {
if(root == null) return;
if(ans.size() <= level) {
ans.add(new ArrayList());
}
ans.get(level).add(root.val);
robot(root.left, level + 1, ans);
robot(root.right, level + 1, ans);
}
}
https://leetcode.com/problems/binary-tree-level-order-traversal-ii/
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
For example:
Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
return its bottom-up level order traversal as:
[
[15,7],
[9,20],
[3]
]
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
robot(root, 0, ans);
Collections.reverse(ans);
return ans;
}
private void robot(TreeNode root, int level, List<List<Integer>> ans) {
if(root == null) return;
if(ans.size() <= level) {
ans.add(new ArrayList());
}
ans.get(level).add(root.val);
robot(root.left, level + 1, ans);
robot(root.right, level + 1, ans);
}
}
https://leetcode.com/problems/maximum-depth-of-binary-tree/
Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
class Solution {
public int maxDepth(TreeNode root) {
if(root == null) return 0;
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return (left == 0 || right == 0) ? (left + right + 1) : Math.max(left, right) + 1;
}
}
https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Example:
Given the sorted array: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
0
/ \
-3 9
/ /
-10 5
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if(nums == null || nums.length == 0) return null;
return robot(nums, 0, nums.length - 1);
}
private TreeNode robot(int[] nums, int start, int end) {
if(start > end) return null;
int mid = start + (end - start) / 2;
TreeNode root = new TreeNode(nums[mid]);
root.left = robot(nums, start, mid - 1);
root.right = robot(nums, mid + 1, end);
return root;
}
}
https://leetcode.com/problems/balanced-binary-tree/
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
class Solution {
public boolean isBalanced(TreeNode root) {
if(root == null) return true;
int left = depth(root.left);
int right = depth(root.right);
return Math.abs(left - right) <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
private int depth(TreeNode root) {
if(root == null) return 0;
return Math.max(depth(root.left), depth(root.right)) + 1;
}
}
https://leetcode.com/problems/binary-search-tree-iterator/
Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.
Calling next() will return the next smallest number in the BST.
Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.
Credits:Special thanks to @ts for adding this problem and creating all test cases.
public class BSTIterator {
List<TreeNode> vector = new ArrayList<TreeNode>();
TreeNode curr = null;
public BSTIterator(TreeNode root) {
curr = root;
// 一直放入左儿子(左)
while(curr != null) {
vector.add(curr);
curr = curr.left;
}
}
/** @return whether we have a next smallest number */
public boolean hasNext() {
return vector.size() != 0 || curr != null;
}
/** @return the next smallest number */
public int next() {
// 一直放入左儿子(左)
while(curr != null) {
vector.add(curr);
curr = curr.left;
}
int ans = 0;
// 访问当前元素(中),把右儿子入栈(右)
if(vector.size() != 0) {
curr = vector.get(vector.size() - 1);
vector.remove(vector.size() - 1);
ans = curr.val;
curr = curr.right;
}
return ans;
}
}
/**
* Your BSTIterator will be called like this:
* BSTIterator i = new BSTIterator(root);
* while (i.hasNext()) v[f()] = i.next();
*/
https://leetcode.com/problems/minimum-depth-of-binary-tree/
Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
class Solution {
public int minDepth(TreeNode root) {
if(root == null) return 0;
int left = minDepth(root.left);
int right = minDepth(root.right);
return (left == 0 || right == 0) ? (left + right + 1) : Math.min(left, right) + 1;
}
}
https://leetcode.com/problems/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.
For 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.
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if(root == null) return false;
if(root.left == null && root.right == null && sum - root.val == 0) return true;
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
}
https://leetcode.com/problems/path-sum-ii/
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
For example:
Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
return
[
[5,4,11,2],
[5,8,4,5]
]
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> ans = new ArrayList<>();
robot(root, sum, ans, new ArrayList<>());
return ans;
}
private void robot(TreeNode root, int sum, List<List<Integer>> ans, List<Integer> tmp) {
if(root == null) return;
tmp.add(root.val);
if(root.left == null && root.right == null && sum == root.val) {
ans.add(new ArrayList(tmp));
tmp.remove(tmp.size() - 1);
return;
}
robot(root.left, sum - root.val, ans, tmp);
robot(root.right, sum - root.val, ans, tmp);
tmp.remove(tmp.size() - 1);
}
}
https://leetcode.com/problems/path-sum-iii/
You are given a binary tree in which each node contains an integer value.
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).
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
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:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
class Solution {
int ans = 0;
public int pathSum(TreeNode root, int sum) {
// 以每个节点开始做算法
robot(root, sum);
return ans;
}
private void robot(TreeNode root, int sum) {
if(root == null) return;
robot(root.left, sum);
// core,以 root 为起点,遍历所有节点求和
countPath(root, sum);
robot(root.right, sum);
}
private void countPath(TreeNode root, int left) {
if(root == null) return;
left -= root.val;
if(left == 0) ans++;
countPath(root.left, left);
countPath(root.right, left);
}
}
https://leetcode.com/problems/flatten-binary-tree-to-linked-list/
Given a binary tree, flatten it to a linked list in-place.
For example,
Given
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like:
1
\
2
\
3
\
4
\
5
\
6
click to show hints.
Hints:
If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.
public class Solution {
public void flatten(TreeNode root) {
if(root == null) return;
flatten(root.left);
flatten(root.right);
TreeNode tmp = root.right;
root.right = root.left;
root.left = null;
// root.right 已经是原来的 root.left
while(root.right != null) root = root.right;
root.right = tmp;
}
}
https://leetcode.com/problems/populating-next-right-pointers-in-each-node/
Given a binary tree
struct TreeLinkNode {
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.
Initially, all next pointers are set to NULL.
Note:
You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
For example,
Given the following perfect binary tree,
1
/ \
2 3
/ \ / \
4 5 6 7
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ / \
4->5->6->7 -> NULL
public class Solution {
public void connect(TreeLinkNode root) {
if(root == null) return;
if(root.left != null) {
root.left.next = root.right;
if(root.next != null) {
root.right.next = root.next.left;
}
}
connect(root.left);
connect(root.right);
}
}
https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/
Follow up for problem "Populating Next Right Pointers in Each Node".
What if the given tree could be any binary tree? Would your previous solution still work?
Note:
You may only use constant extra space.
For example,
Given the following binary tree,
1
/ \
2 3
/ \ \
4 5 7
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ \
4-> 5 -> 7 -> NULL
public class Solution {
public void connect(TreeLinkNode root) {
if(root == null) return;
if(root.left == null && root.right == null) return;
TreeLinkNode p = root.next;
while(p != null) {
if(p.left != null) {
p = p.left;
break;
}
if(p.right != null) {
p = p.right;
break;
}
p = p.next;
}
if(root.right != null) root.right.next = p;
if(root.left != null) root.left.next = root.right == null ? p : root.right;
// 先右子树,因为 next 节点依赖右边
connect(root.right);
connect(root.left);
}
}
https://leetcode.com/problems/binary-tree-maximum-path-sum/
Given a binary tree, find the maximum path sum.
For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
For example:
Given the below binary tree,
1
/ \
2 3
Return 6.
class Solution {
int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
robot(root);
return max;
}
private int robot(TreeNode root) {
if(root == null) return 0;
int left = robot(root.left);
int right = robot(root.right);
int ans = root.val;
if(Math.max(left, right) > 0) {
ans += Math.max(left, right);
}
max = Math.max(max, root.val);
max = Math.max(max, left + root.val);
max = Math.max(max, right + root.val);
max = Math.max(max, left + right + root.val);
return ans;
}
}
https://leetcode.com/problems/sum-root-to-leaf-numbers/
Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path 1->2->3 which represents the number 123.
Find the total sum of all root-to-leaf numbers.
For example,
1
/ \
2 3
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Return the sum = 12 + 13 = 25.
class Solution {
public int sumNumbers(TreeNode root) {
return robot(root, 0);
}
private int robot(TreeNode root, int sum) {
if(root == null) return 0;
sum = sum * 10 + root.val;
if(root.left == null && root.right == null) return sum;
return robot(root.left, sum) + robot(root.right, sum);
}
}
https://leetcode.com/problems/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 {
int ans = 0;
public int sumOfLeftLeaves(TreeNode root) {
robot(root, false);
return ans;
}
private void robot(TreeNode root, boolean isLeft) {
if(root == null) return;
if(root.left == null && root.right == null && isLeft) {
ans += root.val;
return;
}
robot(root.left, true);
robot(root.right, false);
}
}
https://leetcode.com/problems/binary-tree-right-side-view/
Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
For example:
Given the following binary tree,
1 <---
/ \
2 3 <---
\ \
5 4 <---
You should return [1, 3, 4].
Credits:Special thanks to @amrsaqr for adding this problem and creating all test cases.
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> ans = new ArrayList<>();
robot(root, ans, 0);
return ans;
}
private void robot(TreeNode root, List<Integer> ans, int height) {
if(root == null) return;
if(ans.size() <= height) {
ans.add(root.val);
}
ans.set(height, root.val);
robot(root.left, ans, height + 1);
robot(root.right, ans, height + 1);
}
}
https://leetcode.com/problems/count-complete-tree-nodes/
Given a complete binary tree, count the number of nodes.
Definition of a complete binary tree from Wikipedia:
In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.
class Solution {
public int countNodes(TreeNode root) {
if(root == null) return 0;
int left = leftHeight(root);
int right = rightHeight(root);
if(left == right) return (1 << left) - 1;
return countNodes(root.left) + countNodes(root.right) + 1;
}
private int leftHeight(TreeNode root) {
int depth = 0;
while(root != null) {
depth++;
root = root.left;
}
return depth;
}
private int rightHeight(TreeNode root) {
int depth = 0;
while(root != null) {
depth++;
root = root.right;
}
return depth;
}
}
https://leetcode.com/problems/invert-binary-tree/
Invert a binary tree.
4
/ \
2 7
/ \ / \
1 3 6 9
to
4
/ \
7 2
/ \ / \
9 6 3 1
Trivia:
This problem was inspired by this original tweet by Max Howell:
Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
public class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
https://leetcode.com/problems/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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______6______
/ \
___2__ ___8__
/ \ / \
0 _4 7 9
/ \
3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.
class Solution {
TreeNode ans = null;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || p == null || q == null) return null;
int min = Math.min(p.val, q.val);
int max = Math.max(p.val, q.val);
robot(root, min, max);
return ans;
}
private void robot(TreeNode root, int min, int max) {
if(root == null) return;
robot(root.left, min, max);
if(root.val <= max && root.val >= min) {
ans = root;
return;
}
robot(root.right, min, max);
}
}
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == p || root == q) {
return root;
}
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left != null && right != null) return root;
return left == null ? right : left;
}
}
https://leetcode.com/problems/binary-tree-paths/
Given a binary tree, return all root-to-leaf paths.
For example, given the following binary tree:
1
/ \
2 3
\
5
All root-to-leaf paths are:
["1->2->5", "1->3"]
Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> ans = new ArrayList<>();
robot(root, ans, "");
return ans;
}
private void robot(TreeNode root, List<String> ans, String path) {
if(root == null) return;
if(root.left == null && root.right == null) {
ans.add(path + root.val);
return;
}
robot(root.left, ans, path + root.val + "->");
robot(root.right, ans, path + root.val + "->");
}
}
https://leetcode.com/problems/serialize-and-deserialize-binary-tree/
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
For example, you may serialize the following tree
1
/ \
2 3
/ \
4 5
as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
Credits:Special thanks to @Louis1992 for adding this problem and creating all test cases.
public class Codec {
private static final String NULL = "*";
private static final String SEP = ",";
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder ans = new StringBuilder();
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()) {
TreeNode node = queue.poll();
if(node == null) {
ans.append(NULL);
} else {
ans.append(node.val);
queue.add(node.left);
queue.add(node.right);
}
ans.append(SEP);
}
return ans.substring(0, ans.length() - 1).toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data == null) return null;
String[] vals = data.split(",");
if(vals.length == 0 || NULL.equals(vals[0])) return null;
Queue<TreeNode> queue = new LinkedList<>();
TreeNode root = buildNode(vals[0]);
queue.add(root);
TreeNode node = null;
for(int i = 1; i < vals.length; i += 2) {
while((node = queue.poll()) == null);
node.left = buildNode(vals[i]);
node.right = buildNode(i + 1 < vals.length ? vals[i + 1] : NULL);
queue.add(node.left);
queue.add(node.right);
}
return root;
}
private TreeNode buildNode(String val) {
if(val == null || val.equals(NULL)) return null;
return new TreeNode(Integer.valueOf(val));
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
递归
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
robot(root, sb);
return sb.toString();
}
public void robot(TreeNode root, StringBuilder sb) {
if(root == null) {
sb.append("X").append(",");
} else {
sb.append(root.val + "").append(",");
robot(root.left, sb);
robot(root.right, sb);
}
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
Deque<String> nodes = new LinkedList<>();
nodes.addAll(Arrays.asList(data.split(",")));
return buildTree(nodes);
}
public TreeNode buildTree(Deque<String> nodes) {
String val = nodes.remove();
if(val.equals("X")) {
return null;
} else {
TreeNode root = new TreeNode(Integer.valueOf(val));
root.left = buildTree(nodes);
root.right = buildTree(nodes);
return root;
}
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
https://leetcode.com/problems/serialize-and-deserialize-bst/
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure.
The encoded string should be as compact as possible.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
List<Integer> preList = new ArrayList<>();
robot(root, preList);
return preList.toString().substring(1, preList.toString().length() - 1);
}
private void robot(TreeNode root, List<Integer> list) {
if(root == null) return;
list.add(root.val);
robot(root.left, list);
robot(root.right, list);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data == null || data.trim().equals("")) return null;
int[] pre = parse(data);
int[] in = pre.clone();
Arrays.sort(in);
return buildTree(pre, in);
}
private int[] parse(String data) {
int[] array = new int[data.split(",").length];
int i = 0;
for(String val : data.split(",")) {
array[i++] = Integer.valueOf(val.trim());
}
return array;
}
private TreeNode build(int preStart, int inStart, int inEnd, int[] pre, int[] in) {
if(preStart >= pre.length || inStart > inEnd) {
return null;
}
TreeNode root = new TreeNode(pre[preStart]);
int inIndex = 0;
for(int i = inStart; i <= inEnd; i++) {
if(in[i] == root.val) {
inIndex = i;
break;
}
}
root.left = build(preStart + 1, inStart, inIndex - 1, pre, in);
root.right = build(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, pre, in);
return root;
}
private TreeNode buildTree(int[] preorder, int[] inorder) {
return build(0, 0, inorder.length - 1, preorder, inorder);
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
https://leetcode.com/problems/house-robber-iii/
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.
Determine the maximum amount of money the thief can rob tonight without alerting the police.
Example 1:
3
/ \
2 3
\ \
3 1
Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Example 2:
3
/ \
4 5
/ \ \
1 3 1
Maximum amount of money the thief can rob = 4 + 5 = 9.
Credits:Special thanks to @dietpepsi for adding this problem and creating all test cases.
class Solution {
public int rob(TreeNode root) {
if(root == null) return 0;
return Math.max(robIn(root), robEx(root));
}
private int robIn(TreeNode root) {
if(root == null) return 0;
return root.val + robEx(root.left) + robEx(root.right);
}
private int robEx(TreeNode root) {
if(root == null) return 0;
// 可以不抢下一个节点
return rob(root.left) + rob(root.right);
}
}