¶剑指offer – 分治算法
¶剑指 Offer 07. 重建二叉树
Difficulty: 中等
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
1 | 前序遍历 preorder = [3,9,20,15,7] |
返回如下的二叉树:
1 | 3 |
限制:
0 <= 节点个数 <= 5000
Solution
1 | /** |
时间复杂度:$O(N)$,N 为节点数
空间复杂度:$O(N)$,哈希表占用空间 $O(N)$,树创建过程中 $O(\log N) \backsim O(N)$
¶剑指 Offer 16. 数值的整数次方
Difficulty: 中等
实现 ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。
示例 1:
1 | 输入:x = 2.00000, n = 10 |
示例 2:
1 | 输入:x = 2.10000, n = 3 |
示例 3:
1 | 输入:x = 2.00000, n = -2 |
提示:
-100.0 < x < 100.0
- $-2^{31} \leq n \leq 2^{31} - 1$
- $-10^4 \leq x^n \leq 10^4$
Solution
1 | class Solution { |
时间复杂度:$O(\log N)$,二分的时间复杂度为对数级别。
空间复杂度:$O(1)$,res , b 等变量占用常数大小额外空间。
¶剑指 Offer 17. 打印从1到最大的n位数
Difficulty: 简单
输入数字 n
,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
1 | 输入: n = 1 |
说明:
- 用返回一个整数列表来代替打印
- n 为正整数
Solution
1. 不考虑大数问题
1 | class Solution { |
时间复杂度,空间复杂度皆是 $O(10^n)$
2. 考虑大数问题
回溯,排列问题
1 | class Solution { |
注意:回溯算法 可以看 carl 大佬写的专题!
时间复杂度:$O(10^n)$,递归生成的排列数量为 $10^n - 1$。
空间复杂度:$O(10^n)$,中间获得的结果存于 nums 中。
¶剑指 Offer 33. 二叉搜索树的后序遍历序列
Difficulty: 中等
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true
,否则返回 false
。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
1 | 5 |
示例 1:
1 | 输入: [1,6,3,2,5] |
示例 2:
1 | 输入: [1,3,2,6,5] |
提示:
数组长度 <= 1000
Solution
方法一:递归写法
1 | class Solution { |
时间复杂度:$O(N^2)$,每次调用 recur(i,j) 减去一个根节点,因此递归占用 O(N) ;最差情况下(即当树退化为链表),每轮递归都需遍历树所有节点,占用 O(N) 。
空间复杂度:$O(N)$,最差情况下(即当树退化为链表),递归深度将达到 N。
方法二:单调栈
1 | class Solution { |
时间复杂度:$O(N)$,遍历 postorder 所有节点,各节点均入栈/出栈一次,使用 $O(N)$ 时间。
**空间复杂度:**最差情况下,单调栈 stack 存储所有节点,使用 $O(N)$ 额外空间。
¶剑指 Offer 51. 数组中的逆序对
Difficulty: 困难
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
1 | 输入: [7,5,6,4] |
限制:
0 <= 数组长度 <= 50000
Solution
方法一:暴力解法
1 | class Solution { |
时间复杂度:$O(N^2)$,两层遍历
空间复杂度:$O(1)$,count 所需的额外空间
方法二:归并排序
1 | class Solution { |
参考 我自己写的排序算法总结中的归并排序: 排序算法 | CongZ’s Blog (czgitaccount.github.io)
由于主要思想就是归并排序,故时间复杂度与空间复杂度与归并排序相同。
时间复杂度:$O(N\log N)$
空间复杂度:$O(N)$
¶参考资料
图解算法数据结构 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com)