【leetcode】99.(Hard)Recovery Binary Search Tree

解题思路:中序Morris遍历
搜索二叉树就是一棵树,所有左子树中的结点都比根节点的值小,所有右子树中结点的值都比根节点的值大。

这个题的意思是,一个搜索二叉树有两个结点的值被调换了,然后我们要找到这两个结点,修复这个搜索二叉树。

根据题意,只有两个结点的值是互调的,所以这个坏掉的搜索二叉树会有两个地方在中序遍历下大小顺序是不对的。

例如下面这颗树有两个结点被调换了(1和3),本来中序遍历下来应该是[1-2-3]的顺序,但是这颗树按照中序遍历排序是[3-2-1],所以有两个地方[3-2]和[2-1]是不对的,需要调换的结点是是**第一个地方的第一个结点3和第二个地方的第一个结点1。**将这两个结点调换以后顺序就可以变为[1-2-3]了。

在这里插入图片描述

题目希望我们使用O(1)的空间大小。一个树的遍历方式有前序中序后序、递归非递归morris遍历共3*3=9种遍历方式。这里使用中序遍历(二叉搜索树一般使用中序遍历),然后使用morris遍历。
关于morris遍历:
https://blog.csdn.net/zuochao_2013/article/details/78538729
https://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html


提交代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
	public void recoverTree(TreeNode root) {
		if(root==null)	return;
		
		TreeNode swap1=null,swap2=null;
		TreeNode tmp=null,pre=null,cur=root;
		while(cur!=null) {
			if(cur.left==null) {
				if(pre!=null&&pre.val>cur.val) {
					if(swap1==null) {
						swap1=pre;swap2=cur;
					}else {
						swap2=cur;
						//swapTreeNode(swap1,swap2);
					}
				}
				pre=cur;cur=cur.right;
			}else {     // left is not null
				tmp=cur.left;
				while(tmp.right!=null&&tmp.right!=cur)
					tmp=tmp.right;
				
				if(tmp.right==null) {
					tmp.right=cur;
					cur=cur.left;
				}else {
					tmp.right=null;
					
					if(pre!=null&&pre.val>cur.val) {
						if(swap1==null) {
							swap1=pre;swap2=cur;
						}else {
							swap2=cur;
							//swapTreeNode(swap1,swap2);
						}
					}
					pre=cur;
					cur=cur.right;
				}
			}
		}
		swapTreeNode(swap1,swap2);
	}
	
	public void swapTreeNode(TreeNode swap1,TreeNode swap2) {
		int tmp=swap1.val;
		swap1.val=swap2.val;
		swap2.val=tmp;
	}
	
}

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/AXIMI/article/details/84633797
今日推荐