乱序版 ● 剑指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
解题思路:
后序遍历:左右根。
二叉搜索树:
- 左子树中所有节点的值 < 根节点的值;
- 右子树中所有节点的值 > 根节点的值;
- 其左右子树也分别为二叉搜索树。
根据二叉搜索树的定义,可以通过递归,判断所有子树的 正确性 (即其后序遍历是否满足二叉搜索树的定义) ,若所有子树都正确,则此序列为二叉搜索树的后序遍历。
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)