题目地址:
Recover Binary Search Tree
题意是一个二分查找树种的两个元素位置调换,在不改变结构的情况下,恢复这个树。
解法1;
根据平衡二叉树的性质,中跟遍历得到的应该是一个递增序列。
class Solution {
public void recoverTree(TreeNode root) {
List<Integer> vals = new ArrayList<>();
List<TreeNode> nodes = new ArrayList<>();
inorder(root, vals, nodes);
Collections.sort(vals);
for(int i=0;i<vals.size();i++){
nodes.get(i).val=vals.get(i);
}
}
public void inorder(TreeNode root,List<Integer> vals,List<TreeNode> nodes){
if(root==null)return ;
inorder(root.left, vals, nodes);
vals.add(root.val);
nodes.add(root);
inorder(root.right, vals, nodes);
}
}
解法2:
寻找这两个调换的元素,比如序列12345,假设5和2调换,变成15342。
中跟遍历时,用pre记录当前节点的上一个节点。
第一次发现上一个节点值大于当前节点时,该pre节点即是第一个所求节点;
第二次发现上一个节点值大于当前节点时,该当前节点即是第二个所求节点。
*/
class Solution {
TreeNode pre=null ,first=null,second=null;
public void recoverTree(TreeNode root) {
inorder(root);
int tmp = first.val;
first.val = second.val;
second.val = tmp;
}
public void inorder(TreeNode root){
if(root==null)return ;
inorder(root.left);
if(pre==null){
pre=root;
}else{
if(pre.val>root.val){
if(first==null)first=pre;
second=root;
}
pre=root;
}
inorder(root.right);
}
}
解法3:
思路和第二个一样,用栈实现递归。
class Solution {
public void recoverTree(TreeNode root) {
if(root==null)return ;
TreeNode pre=null ,first=null ,second=null ,rt=root;
Stack<TreeNode> st = new Stack<TreeNode>();
while(rt!=null||st.empty()==false){
while(rt!=null){
st.push(rt);
rt=rt.left;
}
rt=st.pop();
if(pre==null){
pre=rt;
}else{
if(pre.val>rt.val){
if(first==null)first=pre;
second=rt;
}
pre=rt;
}
rt=rt.right;
}
int tmp = first.val;
first.val = second.val;
second.val = tmp;
}
}
解法4:
参考其他博主的Morris Traversal方法
非递归且不使用栈,空间复杂度为 O(1) 的遍历方法
class Solution {
public void recoverTree(TreeNode root) {
if(root==null)return ;
TreeNode pre=null ,first=null ,second=null ,p=null ,rt=root;
while(rt!=null){
if(rt.left!=null){
p=rt.left;
while(p.right!=null&&p.right!=rt){
p=p.right;
}
if(p.right==null){
p.right=rt;
rt=rt.left;
continue;
}else{
p.right=null;
}
}
if(pre!=null&&pre.val>rt.val){
if(first==null)first=pre;
second=rt;
}
pre=rt;
rt=rt.right;
}
int tmp = first.val;
first.val = second.val;
second.val = tmp;
}
}