Leetcode 513 力扣
解法一:迭代法,找到最底层第一个值就是目标值,迭代模版直接套用。
public int findBottomLeftValue(TreeNode root) { Queuequeue = 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; }
解法二:递归+回溯(回到根节点继续遍历另外一侧子树)
private int Deep = -1; private int value = 0; public int findBottomLeftValue1(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){ deep++; findLeftValue(root.left,deep); deep--; // findLeftValue(root.left,deep + 1); 三行精简一行,因为deep值没变化 } if (root.right != null) { deep++; findLeftValue(root.right, deep); deep--; // findLeftValue(root.right,deep + 1); } }
Leetcode 112 力扣
解法:递归+回溯
public boolean hasPathSum(TreeNode root, int targetSum) { if (root == null) { return false; } targetSum -= root.val; // 遗漏减去根节点值的操作,只能做一次根节点减除 return traversal(root,targetSum); } private boolean traversal(TreeNode root, int targetSum) { if (root.left == null && root.right == null) { // 包含target 减去路径最后为0和不为0情况 return targetSum == 0; } if (root.left != null) { targetSum -= root.left.val; if (traversal(root.left, targetSum)) {// 递归 return true; } targetSum += root.left.val; // 回溯 } if (root.right != null) { targetSum -= root.right.val; if (traversal(root.right, targetSum)) {// 递归 return true; } targetSum += root.right.val; // 回溯 } return false; }
Leetcode 113 力扣
解法:递归+回溯
public List> pathSum(TreeNode root, int targetSum) { List
> res = new ArrayList<>(); if (root == null){ return res; } List
path = new ArrayList<>(); dfs(root,path,res,targetSum); return res; } private void dfs(TreeNode root, List path, List > res,int targetSum) { path.add(root.val); // 中 // 遇到叶子节点 if (root.left == null && root.right == null){ // 找到了和为 targetsum 的路径 if (targetSum - root.val == 0){ res.add(new ArrayList<>(path)); } return; } // 非叶子节点 if (root.left != null){ dfs(root.left,path,res,targetSum - root.val);//递归,target每次要减去子树作为跟节点时候值 path.remove(path.size()-1);//回溯 } if (root.right != null){ dfs(root.right,path,res,targetSum - root.val);//递归,target每次要减去子树作为跟节点时候值 path.remove(path.size()-1);//回溯 } }
Leetcode 106 力扣
解法:思路简单,实现比较难。
https://www.bilibili.com/video/BV1vW4y1i7dn/?vd_source=f95f3ae208f12eceaadbbce61b28a493
Mapmap; // 方便根据数值查找位置 public TreeNode buildTreeInorderAndPost(int[] inorder, int[] postorder) { map = new HashMap<>(); for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置 map.put(inorder[i], i); } return findNode(inorder, 0, inorder.length, postorder,0, postorder.length); // 前闭后开 } public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) { // 参数里的范围都是前闭后开 if (inBegin >= inEnd || postBegin >= postEnd) { // 不满足左闭右开,说明没有元素,返回空树 return null; } int rootIndex = map.get(postorder[postEnd - 1]); // 找到后序遍历的最后一个元素在中序遍历中的位置 TreeNode root = new TreeNode(inorder[rootIndex]); // 构造结点 int lenOfLeft = rootIndex - inBegin; // 保存中序左子树个数,用来确定后序数列的个数 root.left = findNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin + lenOfLeft); root.right = findNode(inorder, rootIndex + 1, inEnd, postorder, postBegin + lenOfLeft, postEnd - 1); return root; }
Leetcode 105 力扣
解法:思路简单,代码难写。
Mapmap1; public TreeNode buildTreePreAndInorder(int[] preorder, int[] inorder) { map1 = new HashMap<>(); for (int i = 0; i < inorder.length; i++) { // 用map保存中序序列的数值对应位置 map1.put(inorder[i], i); } return findNode1(preorder, 0, preorder.length, inorder, 0, inorder.length); // 前闭后开 } public TreeNode findNode1(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd) { // 参数里的范围都是前闭后开 if (preBegin >= preEnd || inBegin >= inEnd) { // 不满足左闭右开,说明没有元素,返回空树 return null; } int rootIndex = map1.get(preorder[preBegin]); // 找到前序遍历的第一个元素在中序遍历中的位置 TreeNode root = new TreeNode(inorder[rootIndex]); // 构造结点 int lenOfLeft = rootIndex - inBegin; // 保存中序左子树个数,用来确定前序数列的个数 root.left = findNode1(preorder, preBegin + 1, preBegin + lenOfLeft + 1, inorder, inBegin, rootIndex); root.right = findNode1(preorder, preBegin + lenOfLeft + 1, preEnd, inorder, rootIndex + 1, inEnd); return root; }