54. 重建二叉树
题目:
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
题解:
- 将中序遍历的数字和下标存入map,使得查找的效率为O(1);
recur 函数
- 递归结束的条件:左边界left大于右边界right;
- 函数的参数
- root 前序遍历中 根节点的下标;
- left 中序遍历中 该子树的左边界;
- right 中序遍历中 该子树的右边界;
- 在中序遍历数组中以
dic.get(preorder[root])
为中心进行划分。
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) {
if (left > right) return null;
TreeNode node = new TreeNode(preorder[root]);
int i = dic.get(preorder[root]);
node.left = recur(root + 1, left, i - 1);
node.right = recur(root + i - left + 1, i + 1, right);
return node;
}
}
55.数值的整数次方
题目:
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。
题解:
- 如果n为负数,则将其转换为x的倒数求幂;
- 思路是将3^5 转换为 9^2×3 再转换为 81^1 ×3 再转换为 (812)0 ×81×3 ;
- 当指数为0时结束循环,当指数为奇数时令res = res × x,否则继续转换就会造成x的丢失。
public double myPow(double x, int n) {
if(x == 0) return 0;
long b = n;
double res = 1.0;
if(b < 0) {
x = 1 / x;
b = -b;
}
while(b > 0) {
if((b & 1) == 1) res *= x;
x *= x;
b >>= 1;
}
return res;
}
56.二叉搜索树的后序遍历序列
题目:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true
,否则返回 false
。假设输入的数组的任意两个数字都互不相同。
题解:
recur 函数
- 参数说明
- postorder后序遍历的数组;
- i 和 j 是当前子树的左右边界;
- 递归结束的条件
- i >= j 说明子树长度为1 ,返回true,递归结束;
- 未达到结束条件;
- 在左边界向右遍历,找到第一个大于根节点的下标记作m;
- 继续向后遍历,假如最后一个大于根节点的下标为index,将index + 1记作p;
- 假如是二叉搜索树的话,p应该指向右边界,并递归调用recur函数判断左右子树。
public boolean verifyPostorder(int[] postorder) {
return recur(postorder, 0, postorder.length - 1);
}
boolean recur(int[] postorder, int i, int j) {
if(i >= j) return true;
int p = i;
while(postorder[p] < postorder[j]) p++;
int m = p;
while(postorder[p] > postorder[j]) p++;
return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
}
有点累了 ~ 还是要继续冲!