力扣110、257、112、113、106、105-java刷题笔记

一、110. 平衡二叉树 - 力扣(LeetCode)

1.1题目

给定一个二叉树,判断它是否是 

平衡二叉树

  

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:

输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

1.2思路分析

当前根节点的高度为其左孩子右孩子中高度的最大值加一;

二叉树的深度是指从根节点到当前节点最长简单路径边的条数;

二叉树的高度是指从该节点到叶子节点的最长简单路径边的条数。

1.3代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    boolean result = true;
    public boolean isBalanced(TreeNode root) {
        fun(root);
        return result ;

    }
    public int  fun(TreeNode root){
        if( root == null) return 0;
        int left = fun(root.left)+1;
        int right = fun(root.right)+1;
        if(Math.abs(left-right) > 1) result = false;
        return Math.max(left,right);
    }
}

二、257. 二叉树的所有路径 - 力扣(LeetCode)

2.1题目

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]

示例 2:

输入:root = [1]
输出:["1"]

2.2思路分析

记得递归和回溯不分家。

2.3代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> result = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        if(root == null) return result;
        fun(root,path,result);
        return result;
    }
    public void fun(TreeNode root , List<Integer> path,List<String>result){
        // 先将根节点放入到路径中
        path.add(root.val);
        //判断是否递归到跟节点
        if(root.left == null && root.right == null){
            // 此时可以将路径添加到path中
            StringBuilder sb = new StringBuilder();
            for(int i = 0 ; i < path.size() ; i++){
                sb.append(path.get(i)).append("->");
            }
            String sb1 = sb.toString();
            sb1 = sb1.substring(0,sb1.length()-2);
            result.add(sb1);
            return;
        }
        if(root.left != null){
            fun(root.left,path,result);
            // 回溯
            path.remove(path.size()-1);
        }
        if(root.right != null){
            fun(root.right,path,result);
            // 回溯
            path.remove(path.size()-1);
        }
    }

}

三、112. 路径总和 - 力扣(LeetCode)

3.1题目

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

示例 2:

输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。

示例 3:

输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。

3.2思路分析

使用递归法先判断递归的所有终止条件,然后根据题设要求写出递归表达式。

3.3代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int targetSum) {
        if(root == null) return false;
        boolean result = fun(root , targetSum-root.val);
        return result;
    }
    public boolean fun(TreeNode node , int count){
        if(node.left == null && node.right == null && count == 0) return true; 
        if(node.left == null && node.right == null) return false;
        // 遇到叶子节点直接返回
        if(node.left != null ){
        count -= node.left.val;
        if(fun(node.left,count)) return true;
        // 回溯
        count += node.left.val;
        }
        if(node.right != null){
            count -= node.right.val;
            if(fun(node.right,count)) return true;
            // 回溯
            count += node.right.val;
        }
        return false;

    }
}

四、113. 路径总和 II - 力扣(LeetCode)

4.1题目

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]

示例 2:

输入:root = [1,2,3], targetSum = 5
输出:[]

示例 3:

输入:root = [1,2], targetSum = 0
输出:[]

4.2思路分析

这个题和第二个题类似,不同的是要保存所有的路径信息,而不是单纯的存在就行。

4.3代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        List<List<Integer>> resultList = new ArrayList<List<Integer>>();
        if(root == null) return resultList;
// 定义结果数组
        List<Integer> path = new ArrayList<Integer>();
//先减去根节
        fun(root, targetSum-root.val,resultList,path);
        return resultList;
    } 
    public void fun(TreeNode root , int targetSum,  List<List<Integer>> resultList,List<Integer> path ){
        // 先将根节点加入到路径中
        path.add(root.val);
        if(root.left == null && root.right == null ){
            if(targetSum == 0){
            // 此时路径满足条件 将其添加到最终结果中
            resultList.add(new ArrayList<Integer>(path));
            }
// 当结果不满足时直接返回
            return;
        }
        // if(root.left == null && root.right == null) {
        //     return;
        // }
        if(root.left != null){
            targetSum -= root.left.val;
            fun(root.left,targetSum,resultList,path);
            // 不满足条件时回溯
            targetSum += root.left.val;
            path.remove(path.size()-1);
        }
        if(root.right != null){
            targetSum -= root.right.val;
            fun(root.right,targetSum,resultList,path);
            // 不满足条件时回溯
            targetSum += root.right.val;
            path.remove(path.size()-1);
        }

    }
}

五、106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

5.1题目

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]

示例 2:

输入:inorder = [-1], postorder = [-1]
输出:[-1]

提示:

  • 1 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorder 和 postorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder 中
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

5.2思路分析

对数组进行不断切片

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

5.3代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer,Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        for(int i = 0 ; i<inorder.length;i++){
            map.put(inorder[i],i);
        }
        return fun(inorder,0,inorder.length,postorder,0,postorder.length);
    }
    public TreeNode fun(int[] inorder,int inBegin, int inEnd, int[] postorder,int posBegin,int posEnd){
        // 先判断是否为空节点
        if(inBegin >= inEnd && posBegin >= posEnd){
            return null;
        }
        // 找到后续遍历的最后一个元素在中序遍历中的位置
        int rootIndex = map.get(postorder[posEnd-1]);
        // 构造新的节点
        TreeNode root = new TreeNode(inorder[rootIndex]);
        int lenOfLeft = rootIndex-inBegin;
        // 遍历左子树(左闭右开)
        root.left=fun(inorder,inBegin,rootIndex,postorder,posBegin,posBegin+lenOfLeft);
        // 遍历右子树
        root.right=fun(inorder,rootIndex+1,inEnd,postorder,posBegin+lenOfLeft,posEnd-1);
        return root;
    }
}

 六、105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

6.1题目

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]

6.2思路分析

同第5题

6.3代码实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    Map<Integer,Integer>map;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        map = new HashMap<>();
        // 遍历中序数组,并将其放入到map中
        for(int i = 0 ; i<inorder.length;i++){
            map.put(inorder[i],i);
        }
        return fun(preorder,0,preorder.length,inorder,0,inorder.length);
    }
    public TreeNode fun(int[] preorder, int preBegin, int preEnd,int[] inorder, int inBegin,int inEnd){
        // 判断是否为空节点
        if(preBegin >= preEnd && inBegin >= inEnd){
            return null;
        }
        //在中序遍历中找到根节点的下表
        int rootIndex = map.get(preorder[preBegin]);
        // 生成新的树节点
        TreeNode root = new TreeNode(preorder[preBegin]);
        int len = rootIndex-inBegin;
        // 生成根节点的左子树与右子树
        root.left = fun(preorder,preBegin+1,preBegin+1+len,inorder,inBegin,rootIndex);
        root.right = fun(preorder,preBegin+1+len,preEnd,inorder,rootIndex+1,inEnd);
        return root;
    }
}

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值