面试题 04.06. 后继者
https://www.bilibili.com/video/av458351722/
找到二叉搜索树的中序遍历的下一个节点,简单点,找二叉树中序遍历的下一个节点,参考大神代码,结果如下:
List<TreeNode> result = new ArrayList<>();
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
inorder(root);
int index = result.indexOf(p);
if (index != -1) {
if (index == result.size() - 1) {
return null;
}
return result.get(index + 1);
}
return null;
}
public void inorder(TreeNode root) {
if (root == null) {
return;
}
inorder(root.left);
result.add(root);
inorder(root.right);
}
名词解释:
二叉搜索树的特点:
(1)若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
(2)若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
(3)左、右子树本身又各是一棵二叉排序树。
(4)中序遍历是一个递增的序列,
借助搜索二叉树的特点,当当前值<p时,必然在右子树中
当当前值小于p,在需要在左子树中寻找,如果寻找到最大才是p,也就是当前值就是下一个元素,否则就是左子树中的下一个元素。
public TreeNode inorderSuccessor1(TreeNode root, TreeNode p) {
if (root == null || p == null) {
return null;
}
if (p.val >= root.val) {
return inorderSuccessor1(root.right, p);
} else {
TreeNode left = inorderSuccessor1(root.left, p);
return left != null ? left : root;
}
}
重建二叉树
这题必须记录一下,手动我都不会,还用代码实现,这不难为我呢…
先搞一把手动的,(还是看大神博客吧,根据下面的顺序手动还是好高的)https://www.cnblogs.com/jiaxin359/p/9512348.html
前序遍历:根结点 —> 左子树 —> 右子树
中序遍历:左子树—> 根结点 —> 右子树
后序遍历:左子树 —> 右子树 —> 根结点
层次遍历:从上到下,从左到右。
这个的过程有一个重复过程,即找到根,区分出左子树和右子树,再找到左子树的根,继续区分左右子树,一直到分完,是一个递归的过程。
先记录一个失败的案例,去找到左子树的字符串,找到右子树的字符串的时候容易发生越界,难搞。。。
//有一个递归关系
// 找到root 左子树字符串 右子树字符串
//此时 root.left = 左子树字符串的根, root.right = 右子树的根
//终止条件 左子树和右子树的字符串都为空
public TreeNode buildTree(int[] preorder, int[] inorder) {
//终止条件
if (preorder.length == 0 && inorder.length == 0) {
return null;
}
TreeNode root = new TreeNode(preorder[0]);
//找到根在里面的位置
int index = 0;
for (int i = 0; i < inorder.length; i++) {
if (inorder[i] == preorder[0]) {
index = i;
break;
}
}
//此处极易产生越界溢出
int[] preorderleft = Arrays.copyOfRange(preorder, 1, 1 + index);
int[] inorderleft = Arrays.copyOfRange(inorder, 0, index);
int[] preorderright = Arrays.copyOfRange(preorder, index + 1, preorder.length);
int[] inorderright = Arrays.copyOfRange(inorder, index + 1, inorder.length - 1);
root.left = buildTree(preorderleft, inorderleft);
root.right = buildTree(preorderright, inorderright);
return root;
}
官方答案的这部分解析必须记录,特别是最后的索引关系,应该会有很多可以用索引处理,不需要新建数据去转换,代码块就不放了,官网已经很清晰了
.剑指 Offer 16. 数值的整数次方
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
这个应该比较简单,记录为f(base,n)标识base的n次方
如果n%20 则f(base,n)=f(base,n/2)*f(base,n/2)
如果n%2!=0则f(base,n)=f(base,n-1/2)*f(base,n-1/2)*base
如果n0 则等于1
如果n==1 则等于base
愉快的写完代码,然后超时了。。。。,哪位大神看出来了的话,还请指导一下小弟吧,这是什么鬼?
public double myPow(double x, int n) {
if (n == 0) {
return 1;
}
if (n == 1) {
return x;
}
if (n == -1) {
return 1/x;
}
if (n % 2 == 0) {
return myPow(x, n / 2) * myPow(x, n / 2);
} else {
return myPow(x, (n - 1) / 2) * myPow(x, (n - 1) / 2) * x;
}
}
538. 把二叉搜索树转换为累加树
这个不像是递归,感觉就是从右边加到左边,不做描述了