1、leetcode513 找树左下角的值
-
递归法
-
目标:在树的最后一行找到最左边的值
- 保证优先左边搜索,【前中后序都可以,因为没有中间节点的处理逻辑】
- 然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
-
递归三部曲:
- 确定递归函数的参数和返回值
- 参数必须有要遍历的树的根节点,还有就是一个int型的变量用来记录最长深度。
- 确定终止条件
- 当遇到叶子节点的时候,就需要统计一下最大的深度了,所以需要遇到叶子节点来更新最大深度。
- 确定单层递归的逻辑
- 在找最大深度的时候,递归的过程中依然要使用回溯,
- 确定递归函数的参数和返回值
-
代码实现
class Solution { private int maxDepth = Integer.MIN_VALUE;//记录最大深度 private int res = 0;//记录最大深度最左节点的数值 //找深度最大的叶子节点,确保优先左边遍历 public void traversal(TreeNode root, int depth){ if(root.left == null && root.right == null){ if(depth > maxDepth){ maxDepth = depth; res = root.val; } return; } if(root.left!=null){ traversal(root.left, depth+1); } if(root.right!=null){ traversal(root.right, depth+1); } return; } public int findBottomLeftValue(TreeNode root) { traversal(root, 0); return res; } }
-
-
迭代法【层序遍历】【找到最后一层的第一个元素】
class Solution { public int findBottomLeftValue(TreeNode root) { Queue<TreeNode> que = new LinkedList<TreeNode>(); int res = 0; if(root != null){ que.offer(root); } while(!que.isEmpty()){ int size = que.size(); for(int i=0; i<size; i++){ TreeNode node = que.poll(); if(i==0){ res = node.val;//记录每层第一个元素,最后值为最后一层的第一个元素值 } if(node.left!=null){ que.offer(node.left); } if(node.right!=null){ que.offer(node.right); } } } return res; } }
2、leetcode112 路径总和
-
递归法
-
代码实现
class Solution { public boolean hasPathSum(TreeNode root, int targetSum) { if(root == null){ return false; } targetSum -= root.val; if(root.left==null && root.right==null){//root为叶子节点 return targetSum==0; } if(root.left!=null){//从左子树找到路径 if(hasPathSum(root.left, targetSum)){ return true; } } if(root.right!=null){//从右子树找到路径 if(hasPathSum(root.right, targetSum)){ return true; } } return false; } }
-
3、leetcode106 从中序与后序遍历序列构造二叉树
-
步骤
-
第一步:如果后序/中序数组大小为零的话,说明是空节点了。
-
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
- 因为后序是左右中,能够最后一个元素确定root节点
-
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
-
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
- 通过root.val切割中序数组
-
第五步:切割后序数组,切成后序左数组和后序右数组
- 通过中序左数组的长度切割后序数据【因此只能先切割中序数组】
注意:切割标准统一,例如:均为左闭右开形式
-
第六步:递归处理左区间和右区间
-
-
代码实现
class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { if(postorder.length == 0){ return null; } TreeNode root = new TreeNode(postorder[postorder.length-1]); if(postorder.length == 1){ return root; } int index = 0; for(index = 0; index<inorder.length; index++){ if(inorder[index] == root.val){ break; } } int[] leftInorder = Arrays.copyOfRange(inorder,0,index); int[] rightInorder = Arrays.copyOfRange(inorder,index+1,inorder.length); postorder = Arrays.copyOfRange(postorder,0,postorder.length-1); int[] leftPostorder = Arrays.copyOfRange(postorder, 0, leftInorder.length); int[] rightPostorder = Arrays.copyOfRange(postorder, leftInorder.length, postorder.length); root.left = buildTree(leftInorder, leftPostorder); root.right = buildTree(rightInorder, rightPostorder); return root; }
4、leetcode105 从前序与中序遍历序列构造二叉树
-
思路与上一题一致
-
代码实现
class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { if(preorder.length == 0){ return null; } TreeNode root = new TreeNode(preorder[0]); if(preorder.length == 1){ return root; } int index = 0; for(index = 0; index<inorder.length; index++){ if(inorder[index] == root.val){ break; } } int[] leftInorder = Arrays.copyOfRange(inorder,0,index); int[] rightInorder = Arrays.copyOfRange(inorder,index+1,inorder.length); preorder = Arrays.copyOfRange(preorder,1,preorder.length); int[] leftPretorder = Arrays.copyOfRange(preorder, 0, leftInorder.length); int[] rightPretorder = Arrays.copyOfRange(preorder, leftInorder.length, preorder.length); root.left = buildTree(leftPretorder, leftInorder); root.right = buildTree(rightPretorder, rightInorder); return root; } }