513找树左下角的值
https://leetcode.cn/problems/find-bottom-left-tree-value/
思路:dfs前序遍历(往下传depth, 更改记录最深层数和左下角值的全局变量); dfs后序遍历(往上传height + 左下值); bfs层序遍历
class Solution { //dfs前序遍历(往下传depth, 更改记录最深层数和左下角值的全局变量)
public int findBottomLeftValue(TreeNode root) {
int[] leftBottom = new int[]{0};
int[] maxDepth = new int[]{0};
dfs(root, 0, leftBottom, maxDepth);
return leftBottom[0];
}
private void dfs(TreeNode root, int depth, int[] leftBottom, int[] maxDepth) {
if (root == null) return;
depth++;
if (depth > maxDepth[0]) {
maxDepth[0] = depth;
leftBottom[0] = root.val;
}
dfs(root.left, depth + 1, leftBottom, maxDepth);
dfs(root.right, depth + 1, leftBottom, maxDepth);
}
}
class Solution { //dfs后序遍历(往上传height + 左下值)
public int findBottomLeftValue(TreeNode root) {
int[] result = dfs(root);
return result[1];
}
private int[] dfs(TreeNode root) { // return {maxheight, leftcorner value}
if (root == null) return new int[]{0, 0};
int[] leftReturn = dfs(root.left);
int[] rightReturn = dfs(root.right);
if (leftReturn[0] == 0 && rightReturn[0] == 0) {
return new int[]{1, root.val};
} else if (leftReturn[0] >= rightReturn[0]) {
return new int[]{leftReturn[0] + 1, leftReturn[1]};
} else {
return new int[]{rightReturn[0] + 1, rightReturn[1]};
}
}
}
class Solution { //bfs
public int findBottomLeftValue(TreeNode root) {
int result = 0;
Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode cur = queue.poll();
if (i == 0) result = cur.val;
if (cur.left != null) queue.offer(cur.left);
if (cur.right != null) queue.offer(cur.right);
}
}
return result;
}
}
112路径总和
https://leetcode.cn/problems/path-sum/
思路用dfs,如果从下向上 post-order dfs,那么返回值是一个set,这个set包含所有从根往下的path sum,还需要不停更新太麻烦了。选择从上向下传prefix sum的dfs.
class Solution { //从上向下 pre-order dfs
public boolean hasPathSum(TreeNode root, int targetSum) {
return dfs(root, 0, targetSum);
}
private boolean dfs(TreeNode root, int prefix, int targetSum) {
if (root == null) return false;
prefix += root.val;
if (root.left == null && root.right == null) return prefix == targetSum;
if (dfs(root.left, prefix, targetSum) || dfs(root.right, prefix, targetSum)) return true;
return false;
}
}
// 更简洁的是往下传时更改 targetSum的值,减去当前根的值,少传一个参数
class Solution { //从上向下 pre-order dfs
public boolean hasPathSum(TreeNode root, int targetSum) {
return dfs(root, targetSum);
}
private boolean dfs(TreeNode root, int targetSum) {
if (root == null) return false;
targetSum -= root.val;
if (root.left == null && root.right == null) return 0 == targetSum;
if (dfs(root.left, targetSum) || dfs(root.right, targetSum)) return true;
return false;
}
}
113 路径总和ii
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
dfs(root, targetSum, path, result);
return result;
}
private void dfs(TreeNode root, int targetSum, List<Integer> path, List<List<Integer>> result) {
if (root == null) {
return;
}
path.add(root.val);
targetSum -= root.val;
if (root.left == null && root.right == null && targetSum == 0) {
result.add(new ArrayList(path));
}
dfs(root.left, targetSum, path, result);
dfs(root.right, targetSum, path, result);
path.remove(path.size() - 1);
}
}
106 从中序与后序遍历序列构造二叉树
https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return build(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1, map);
}
private TreeNode build(int[] inorder, int inLeft, int inRight, int[] postorder, int postLeft, int postRight, Map<Integer, Integer> map) {
if (inLeft > inRight) return null;
TreeNode root = new TreeNode(postorder[postRight]);
int rootIndex = map.get(root.val);
int leftCount = rootIndex - inLeft;
root.left = build(inorder, inLeft, rootIndex - 1, postorder, postLeft, postLeft + leftCount - 1, map);
root.right = build(inorder, rootIndex + 1, inRight, postorder, postLeft + leftCount, postRight - 1, map); //bug,post的最后点为根
return root;
}
}
105 从前序与中序遍历序列构造二叉树
https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return build(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, map);
}
private TreeNode build(int[] preorder, int preLeft, int preRight, int[] inorder, int inLeft, int inRight, Map<Integer, Integer> map) {
if (preLeft > preRight) return null;
TreeNode root = new TreeNode(preorder[preLeft]);
int rootIndex = map.get(root.val);
int leftCount = rootIndex - inLeft;
root.left = build(preorder, preLeft + 1, preLeft + leftCount, inorder, inLeft, rootIndex - 1, map);
root.right = build(preorder, preLeft + 1 + leftCount, preRight, inorder, rootIndex + 1, inRight, map);
return root;
}
}