513.找树左下角的值
/ 递归法 class Solution { private int Deep = -1; private int value = 0; public int findBottomLeftValue(TreeNode root) { value = root.val; findLeftValue(root,0); return value; } private void findLeftValue (TreeNode root,int deep) { if (root == null) return; if (root.left == null && root.right == null) { if (deep > Deep) { value = root.val; Deep = deep; } } if (root.left != null) findLeftValue(root.left,deep + 1); if (root.right != null) findLeftValue(root.right,deep + 1); } }
容易错误的认为一直使用递归向左孩子找,就是最后的结果,但是有可能找到的并不是最后一行。那么我们就要判断一下(首先是最后一行然后是位置最左),这道题最容易想的其实是层序法(迭代)。
//迭代法 class Solution { public int findBottomLeftValue(TreeNode root) { Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int res = 0; while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { TreeNode poll = queue.poll(); if (i == 0) { res = poll.val; } if (poll.left != null) { queue.offer(poll.left); } if (poll.right != null) { queue.offer(poll.right); } } } return res; } }
112. 路径总和
class Solution { public boolean hasPathSum(TreeNode root, int sum) { if (root == null) { return false; } Queue<TreeNode> queNode = new LinkedList<TreeNode>(); Queue<Integer> queVal = new LinkedList<Integer>(); queNode.offer(root); queVal.offer(root.val); while (!queNode.isEmpty()) { TreeNode now = queNode.poll(); int temp = queVal.poll(); if (now.left == null && now.right == null) { if (temp == sum) { return true; } continue; } if (now.left != null) { queNode.offer(now.left); queVal.offer(now.left.val + temp); } if (now.right != null) { queNode.offer(now.right); queVal.offer(now.right.val + temp); } } return false; } }
class Solution { List<List<Integer>> ret = new LinkedList<List<Integer>>(); Deque<Integer> path = new LinkedList<Integer>(); public List<List<Integer>> pathSum(TreeNode root, int targetSum) { dfs(root, targetSum); return ret; } public void dfs(TreeNode root, int targetSum) { if (root == null) { return; } path.offerLast(root.val); targetSum -= root.val; if (root.left == null && root.right == null && targetSum == 0) { ret.add(new LinkedList<Integer>(path)); } dfs(root.left, targetSum); dfs(root.right, targetSum); path.pollLast(); } }
113.路径总和2
● 106.从中序与后序遍历序列构造二叉树
class Solution { int post_idx; int[] postorder; int[] inorder; Map<Integer, Integer> idx_map = new HashMap<Integer, Integer>(); public TreeNode helper(int in_left, int in_right) { // 如果这里没有节点构造二叉树了,就结束 if (in_left > in_right) { return null; } // 选择 post_idx 位置的元素作为当前子树根节点 int root_val = postorder[post_idx]; TreeNode root = new TreeNode(root_val); // 根据 root 所在位置分成左右两棵子树 int index = idx_map.get(root_val); // 下标减一 post_idx--; // 构造右子树 root.right = helper(index + 1, in_right); // 构造左子树 root.left = helper(in_left, index - 1); return root; } public TreeNode buildTree(int[] inorder, int[] postorder) { this.postorder = postorder; this.inorder = inorder; // 从后序遍历的最后一个元素开始 post_idx = postorder.length - 1; // 建立(元素,下标)键值对的哈希表 int idx = 0; for (Integer val : inorder) { idx_map.put(val, idx++); } return helper(0, inorder.length - 1); } }
105.从前序与中序遍历序列构造二叉树
class Solution { private Map<Integer, Integer> indexMap; public TreeNode myBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) { if (preorder_left > preorder_right) { return null; } // 前序遍历中的第一个节点就是根节点 int preorder_root = preorder_left; // 在中序遍历中定位根节点 int inorder_root = indexMap.get(preorder[preorder_root]); // 先把根节点建立出来 TreeNode root = new TreeNode(preorder[preorder_root]); // 得到左子树中的节点数目 int size_left_subtree = inorder_root - inorder_left; // 递归地构造左子树,并连接到根节点 // 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素 root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1); // 递归地构造右子树,并连接到根节点 // 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素 root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right); return root; } public TreeNode buildTree(int[] preorder, int[] inorder) { int n = preorder.length; // 构造哈希映射,帮助我们快速定位根节点 indexMap = new HashMap<Integer, Integer>(); for (int i = 0; i < n; i++) { indexMap.put(inorder[i], i); } return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1); } }