513.找树左下角的值
本地递归偏难,反而迭代简单属于模板题
最底层最左边节点的值 先找到树的最深层,只要找到树的最深层无论是左节点还是右节点都是最左边节点的值
class Solution {
//全局变量
//深度
int Max_depth = -1;
//结果值
int res = 0;
public int findBottomLeftValue(TreeNode root) {
if(root == null){
return res;
}
// res = root.val;
traversal(root,0);
return res;
}
private void traversal(TreeNode root,int depth){
if(root.left == null && root.right == null){
if(depth > Max_depth){
Max_depth = depth;
res = root.val;
}
return;
}
//左
if(root.left != null){
depth++;
traversal(root.left,depth);
depth--;
}
if(root.right != null){
depth++;
traversal(root.right,depth);
depth--;
}
return;
}
}
112.路径总和
题目要求找到一条路径即可,递归函数返回值为boolean即可
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
List<Integer> path = new ArrayList<>();
if(root == null) return false;
return backTracking(root,path,targetSum);
}
//确定递归方法及参数
public boolean backTracking(TreeNode root,List<Integer> path,int targetSum){
path.add(root.val);
//确定递归终止条件
if(root.left == null && root.right == null){
int i=0;
for(int j:path){
i+=j;
}
return i == targetSum;
}
//确定递归单层逻辑
if(root.left != null){
if(backTracking(root.left,path,targetSum)){//先往左一直遍历 返回结果
return true; //找到了 targetSum
}
path.remove(path.size()-1); //遍历到最底部 回溯
}
if(root.right != null){
if(backTracking(root.right,path,targetSum)){//往右遍历 返回结果
return true; //找到了 targetSum
}
path.remove(path.size()-1);
}
return false;
}
}
113.路径总和ii
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
List<List<Integer>> resList = new ArrayList<>();
if(root == null){
return resList;
}
List<Integer> path = new ArrayList<>();
tra(resList,targetSum,path,root);
return resList;
}
private void tra(List<List<Integer>> resList,int targetSum,List<Integer> path,TreeNode root){
path.add(root.val);
//遇到了叶子节点
if(root.left == null && root.right == null){
int sum = 0;
for(int s : path){
sum += s;
}
if(sum == targetSum){
resList.add(new ArrayList<>(path));
}
}
//左确认递归单层逻辑 路径回溯
if(root.left != null){
tra(resList,targetSum,path,root.left);
path.remove(path.size() - 1);
}
if(root.right != null){
tra(resList,targetSum,path,root.right);
path.remove(path.size() - 1);
}
}
}
106.从中序与后序遍历构造二叉树
1:如果数组大小为0说明是空节点
2.如果不为空 取后序数组最后一个元素为根节点元素
3.找到根节点到中序数组的位置作为切割点
4.切割中序数组,切成中序左数组和中序右数组
5.切割后序数组,切成后序左数组与后序右数组
中序数组中通过根节点切开,左边为根节点左子树节点个数,右边为根节点右子树节点个数
6.递归处理左区间(中序左数组与后序左数组)与右区间(中序右数组与后序右数组)
确定好区间定义划分 左闭右开
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(postorder.length == 0 || inorder.length == 0){
return null;
}
return buildHelper(inorder,0,inorder.length,postorder,0,postorder.length);
}
private TreeNode buildHelper(int[] inorder,int inorderStart,int inorderEnd,int[] postorder,int postorderStart,int postorderEnd){
if(postorderStart == postorderEnd) return null;
int rootVal = postorder[postorderEnd - 1];
TreeNode root = new TreeNode(rootVal);
int Midindex;
for(Midindex = inorderStart;Midindex < inorderEnd;Midindex++){
if(rootVal == inorder[Midindex]){
break;
}
}
//左闭右开
int leftInorderStart = inorderStart;
int leftInorderEnd = Midindex;
int rightInorderStart = Midindex+1;
int rightInorderEnd = inorderEnd;
int leftPostStart = postorderStart;
int leftPostEnd = postorderStart + (Midindex - inorderStart);
int rightPostderStart = postorderStart + (Midindex - inorderStart);
int rightPostEnd = postorderEnd - 1;
root.left = buildHelper(inorder,leftInorderStart,leftInorderEnd,postorder,leftPostStart,leftPostEnd);
root.right = buildHelper(inorder,rightInorderStart,rightInorderEnd,postorder,rightPostderStart,rightPostEnd);
return root;
}
}
105.从前序与中序遍历构造二叉树
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length == 0 || inorder.length == 0){
return null;
}
return buildHelper(inorder,0,inorder.length,preorder,0,preorder.length);
}
private TreeNode buildHelper(int[] inorder,int inorderStart,int inorderEnd,int[] preorder,int preorderStart,int preorderEnd){
if(preorderStart == preorderEnd) return null;
int rootVal = preorder[preorderStart];
TreeNode root = new TreeNode(rootVal);
int midIndex;
for(midIndex = inorderStart;midIndex < inorder.length;midIndex++){
if(inorder[midIndex] == rootVal){
break;
}
}
int leftInorderStart = inorderStart;
int leftInorderEnd = midIndex;
int rightInorderStart = midIndex+1;
int rightInorderEnd = inorderEnd;
int leftPreorderStart = preorderStart + 1;
int leftPreorderEnd = preorderStart + 1 +midIndex - inorderStart;
int rightPreorderStart = preorderStart + 1 +midIndex - inorderStart;
int rightPreorderEnd = preorderEnd;
root.left = buildHelper(inorder,leftInorderStart,leftInorderEnd,preorder,leftPreorderStart,leftPreorderEnd);
root.right = buildHelper(inorder,rightInorderStart,rightInorderEnd,preorder,rightPreorderStart,rightPreorderEnd);
return root;
}
}