好家伙,第一次独立的完成hard的题(当然莫里斯遍历算法我还是不会,逃。。。)

99. 恢复二叉搜索树_数据结构

先是自己写的朴素的O(n)代码

99. 恢复二叉搜索树_结点_02

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public void recoverTree(TreeNode root) {
List<TreeNode> list = new ArrayList<>();
inorder(root, list);
TreeNode a = null;
TreeNode b = null;
for (int i = 0; i < list.size() - 1; i++){
if (list.get(i).val > list.get(i+1).val){
b = list.get(i+1); //第一次遇到的b结点可能不是要交换的结点
if (a == null) a = list.get(i); //a是绝对要进行交换的结点
}
}
if (a != null && b != null){
int tmp = a.val;
a.val = b.val;
b.val = tmp;
}
}
public void inorder(TreeNode root, List<TreeNode> list){
if (root == null) return;
inorder(root.left, list);
list.add(root);
inorder(root.right, list);
}

}

CV来的莫里斯中序遍历,日后再看哪个讲得好学习吧

public void recoverTree(TreeNode root) {
//记录错误的两个值
TreeNode x = null, y = null;
//记录中序遍历当前节点的前驱
TreeNode pre = null;
//用来完成Morris连接的寻找前驱的指针
TreeNode predecessor = null;
while(root != null) {
if(root.left != null) {//左子树不为空,1、链接root节点的前驱,他的前驱还没访问,所以root不能现在访问,继续访问root左子树 2、root节点访问,并且断开root节点的前驱连接,然后访问root的右子树
predecessor = root.left;
while(predecessor.right != null && predecessor.right != root) {
predecessor = predecessor.right;
}
if(predecessor.right == root) {//说明了1已经执行过了,我们执行2
//访问
if(pre != null && pre.val > root.val) {
if(x == null) x = pre;
y = root;
}
//更新前驱,为下一个节点做准备
pre = root;
//断开前驱连接
predecessor.right = null;
//访问root右子树
root = root.right;
}else {//predecessor.right != root,说明了还没执行过1
predecessor.right = root;
root = root.left;
}
}else {//root.left == null,root不需要链接节点的前驱(他的前驱其实就是pre(第一个节点pre为null),且已经被访问过了),那么直接访问root
//访问
if(pre != null && pre.val > root.val) {
if(x == null) x = pre;
y = root;
}
//更新前驱,为下一个节点做准备
pre = root;
//访问root的右子树
root = root.right;
}
}
swap(x, y);
}

public void swap(TreeNode x, TreeNode y) {
int tmp = x.val;
x.val = y.val;
y.val = tmp;
}