前言
二叉搜索树的特性需要好好利用,与中序遍历紧密相关。有时还可以通过左<中<右来非递归寻找节点值。
一、案例
二、题解
package com.xhu.offer.offerII;
//二叉搜索树中的中序后继
public class InorderSuccessor {
//中序遍历
//总结:二叉搜索树的特性需要好好利用,与中序遍历紧密相关。有时还可以通过左<中<右来非递归寻找节点值。
TreeNode dummyNode = new TreeNode(-1);
boolean flag = false, flag2 = false;
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
inOrder(root, p);
return dummyNode.right;
}
private void inOrder(TreeNode root, TreeNode p) {
//剪枝
if (flag2 || root == null) return;
inOrder(root.left, p);
if (flag) {
flag = false;
flag2 = true;
dummyNode.right = root;
}
if (p.val == root.val) flag = true;
inOrder(root.right, p);
}
//优化
TreeNode res = null;
public TreeNode inorderSuccessor2(TreeNode root, TreeNode p) {
if (root == null) return res;
inorderSuccessor2(root, p);
if (root.val > p.val && !flag) {
flag = true;
res = root;
return res;
}
inorderSuccessor2(root, p);
return res;
}
//优化,简单递归
//总结:这种复制地址的方式可以做到类似成员变量的效果,但是需分成两个函数写,好处是比堆中取要快一些,这些局部变量存在于线程私有栈中。
public TreeNode inorderSuccessor3(TreeNode root, TreeNode p) {
boolean[] flag = new boolean[]{false};
TreeNode[] res = new TreeNode[]{null};
order(root, p, flag, res);
return res[0];
}
private void order(TreeNode root, TreeNode p, boolean[] flag, TreeNode res[]) {
if (flag[0] || root == null) return;
order(root.left, p, flag, res);
if (p.val < root.val && !flag[0]) {
flag[0] = true;
res[0] = root;
}
order(root.right, p, flag, res);
}
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
}
总结
1)二叉搜索树的特性需要好好利用,与中序遍历紧密相关。有时还可以通过左<中<右来非递归寻找节点值。
2)复制地址的方式可以做到类似成员变量的效果,但是需分成两个函数写,好处是比堆中取要快一些,这些局部变量存在于线程私有栈中。
参考文献
[1] LeetCode 原题