算法day20 | 二叉树:总结、树左下角值、路径总和、根据遍历构建树及迭代法初步学习

1. 二叉树合并

1.1 链接

https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal

1.2 关键知识点

  • 合并的逻辑:把节点对应值相加,如果为空就返回另外一个树的

1.3 自己遇到的细节问题

  • 判断为空只用对两个树分别判断就好,不必要写他们同时为空的情况,同时为空自然返回null

1.4 题解

/**
 * 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 TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
        if(root1 == null){return root2;}
        if(root2 == null){return root1;}

        root1.val += root2.val;

        root1.left = mergeTrees(root1.left, root2.left);
        root1.right = mergeTrees(root1.right, root2.right);

        return root1;
    }
}

2.654. 最大二叉树

2.1 链接

https://leetcode.cn/problems/maximum-binary-tree

2.2 关键知识点

  • 根据数组及其下标构建二叉树的基本模板(重点是根节点的跳过问题、数组定义保持左闭右开)

2.3 自己遇到的细节问题

  • 求最大值及其下标那边忘记更新下标
  • 终止条件只写了if(end - begin == 1){ return new TreeNode(nums[begin]);}这样的不行的,null的返回是必须的,这样会导致栈溢出(递归无法终止)

2.4 题解

/**
 * 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 TreeNode constructMaximumBinaryTree(int[] nums) {
        TreeNode root = constructMaximumBinaryTreeIdx(nums, 0, nums.length);
        return root;
    }
    public TreeNode constructMaximumBinaryTreeIdx(int[] nums, int begin, int end){
        if(end <= begin) {return null;} //一定要有null的返回,因为可能数组长度为2
        // if(end - begin == 1){ return new TreeNode(nums[begin]);} //叶子节点直接返回   使用构造函数初始化要加new

        //找当前区间最大值(左闭右开)下标
        int max = nums[begin];
        int maxIdx = begin;
        for(int i = begin + 1; i < end; i ++){ //由于初始化赋值给begin,因此可以从+1开始
            if(nums[i] > max){//下标和值都要更新
                maxIdx = i;
                max = nums[i];
            }
        }

        TreeNode root = new TreeNode(nums[maxIdx]);
        root.left = constructMaximumBinaryTreeIdx(nums , begin, maxIdx);
        root.right = constructMaximumBinaryTreeIdx(nums , maxIdx + 1, end);
        return root;
    }
}

3.二叉搜索树中的搜索:递归

3.1 链接

https://leetcode.cn/problems/search-in-a-binary-search-tree

3.2 关键知识点

4.3 自己遇到的细节问题

  • 注意返回根节点

4.4 题解

/**
 * 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 TreeNode searchBST(TreeNode root, int val) {
        if(root == null || root.val == val){
            return root;
        }

        if(root.val > val){
            return searchBST(root.left, val);
        }else{
            return searchBST(root.right, val);
        }
    }
}

4.验证二叉搜索树:中序遍历

4.1 链接

https://leetcode.cn/problems/validate-binary-search-tree/

4.2 关键知识点

  • 基础是二叉搜索树中序遍历是递增的
  • 比较的连续性:由于根据树的左右节点判断没有保证整个比较的连续性,因此需要利用一个临时变量存储中序遍历时上一个节点的值,来构造一个连续比较。(root->val > root->left->val && root->val < root->right->val不行的原因如下图)
    在这里插入图片描述
  • 遍历第一个节点时,也需要有一个初始值进行比较,由于测试用例中有MIN_VALUE,因此两种方法:
    • 定义为long long maxVal = LONG_MIN;
    • 对第一个节点做处理,如果

4.3 自己遇到的细节问题

  • 注意新建的tmp是treenode,才是null,如果是int,未初始化值为 0,会影响判断

4.4 题解

/**
 * 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 {
    TreeNode tmp;
    public boolean isValidBST(TreeNode root) {
        if(root == null) {return true;}

        boolean left = isValidBST(root.left);
        if(!left){return false;}

        if(tmp == null || root.val > tmp.val){
            tmp = root;
        }else{
            return false;
        }

        boolean right = isValidBST(root.right);
        if(!right){return false;}

        return (right && left);
    }
}

4.二叉深度遍历:迭代法学习1.0

  • 为什么要用栈?粗糙的理解:越后进的深度越大,在深度优先遍历中越是先处理的。 所以需要用到栈
  • 非统一方法
    • 中序遍历
      • 先一路向左直到没有左孩子为止,然后再弹出看有没有右孩子,没有再接着弹出,有的话就让右孩子入栈,再一路向左
    • 前、后序遍历:利用栈push进去,再pop出并且push入右左孩子节点(注意顺序);
  • 统一方法:由于通过null节点标记中间节点,while中包括if(curr != null){}else{}判断,如果不是null,pop后加入左中null右,如果是null就pop出null后加入结果集(遍历所需的判断逻辑在这)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值