乱序版 ● 剑指offer每日算法题打卡题解—— 分治算法(题号7,33,64)

Posted 寂静花开

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乱序版 ● 剑指offer每日算法题打卡题解—— 分治算法(题号7,33,64)相关的知识,希望对你有一定的参考价值。

打卡day14

第一题:剑指 Offer 64. 求1+2+…+n

求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

示例 1:
输入: n = 3
输出: 6

示例 2:
输入: n = 9
输出: 45

限制:
1 <= n <= 10000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/qiu-12n-lcof

解题思路:
用的try catch,和递归,有点取巧了
java代码:

class Solution {
    int[] res=new int[]{0};
    public int sumNums(int n) {
        try{
            return res[n];
        }catch(Exception e){
            return n+sumNums(n-1);
        }
    }
} 

第二题:剑指 Offer 07. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

示例 2:
Input: preorder = [-1], inorder = [-1]
Output: [-1]

限制:
0 <= 节点个数 <= 5000

来源:力扣(LeetCode)
链接:添加链接描述
解题思路:
前序遍历:根左右
中序遍历:左根右
根据 前序遍历 确定根节点,将中序遍历的左根右划分出来。
前序遍历和中序遍历都不含有重复数字,此题中的二叉树无重复节点
利用递推,是分治算法的体现。

java代码:

class Solution {
    int[] preorder;//先序遍历。
    HashMap<Integer, Integer> dic = new HashMap<>();//创建哈希表储存中序遍历的值和索引
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        this.preorder = preorder;
        for(int i = 0; i < inorder.length; i++){
            dic.put(inorder[i], i);//存入中序遍历的值和下标
        }
        return recur(0, 0, inorder.length - 1);
    }
    TreeNode recur(int root, int left, int right) {//root是先序遍历的索引,left和right是中序遍历的索引
        if(left > right) {
        	return null;                          // 递归终止
        }
        TreeNode node = new TreeNode(preorder[root]);          // 建立根节点
        int i = dic.get(preorder[root]);                       // 从dic中获取中序遍历中根节点的索引
        node.left = recur(root + 1, left, i - 1);              // 左子树递归,左子树的根节点索引是root+1,左边界是left,右边界是中序遍历中的根节点索引+1
        node.right = recur(root + i - left + 1, i + 1, right); // 右子树递归,右子树的根节点的索引是  左子树长度(左子树的左边-右边)+1
        return node;                                           // 返回根节点
    }
}

第三题:剑指 Offer 33. 二叉搜索树的后序遍历序列

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

参考以下这颗二叉搜索树:

     5
    / \\
   2   6
  / \\
 1   3

示例 1:
输入: [1,6,3,2,5]
输出: false

示例 2:
输入: [1,3,2,6,5]
输出: true

提示:
数组长度 <= 1000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof

解题思路:
后序遍历:左右根。
二叉搜索树:

  1. 左子树中所有节点的值 < 根节点的值;
  2. 右子树中所有节点的值 > 根节点的值;
  3. 其左右子树也分别为二叉搜索树。
    根据二叉搜索树的定义,可以通过递归,判断所有子树的 正确性 (即其后序遍历是否满足二叉搜索树的定义) ,若所有子树都正确,则此序列为二叉搜索树的后序遍历。

java代码:

class Solution {
     public boolean verifyPostorder(int[] postorder) {
        return recur(postorder, 0, postorder.length - 1);
    }
    boolean recur(int[] postorder, int i, int j) {
        if(i >= j){//postorder.length <= 1
            return true;
        }
        int a = i;
        while(postorder[a] < postorder[j]){
            a++;
        }
        int m = a;//第一个大于根节点的节点
        while(postorder[a] > postorder[j]) {
            a++;
        }
        //判断树,左子树,右子树
        return a == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
    }
}

以上是关于乱序版 ● 剑指offer每日算法题打卡题解—— 分治算法(题号7,33,64)的主要内容,如果未能解决你的问题,请参考以下文章

乱序版 ● 剑指offer每日算法题打卡题解—— 查找算法 (题号3,4,11,53)

乱序版 ● 剑指offer每日算法题打卡题解——分治算法(题号17,14)

乱序版 ● 剑指offer每日算法题打卡题解——数学 (题号39,66)

乱序版 ● 剑指offer每日算法题打卡题解——动态规划(题号19,49,60)

乱序版 ● 剑指offer每日算法题打卡题解——动态规划 (题号10,63)

乱序版 ● 剑指offer每日算法题打卡题解——栈与队列(题号59)