Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.Note:

A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?


这个题我看到的想法是先把所有element in order走一遍,然后存进O(n) space的array. 然后排序。排序好以后重新建一个BST.

但是这种naive solution太暴力了,不知道该怎么优化。

但是要做到constant space, 。。。。不知道怎么搞。。。难怪这题是Hard level...


Recover Binary Search Tree_第1张图片

我做的时候大概知道要keep reference of 两个觉得不对劲的Node。比如他比left 小 || 比right 大,这很明显就不对。 但是我就算keep了两个Node, 没办法交换呀,因为需要其parent才可以操控他们交换。还有就是我是不是还得save一个left or right告诉parent这是在左边还是右边。。。


看完答案感觉傻逼了。。。原来根本不用交换node reference. 只要记录node reference,交换value就好了。

然后我开始写代码: 用pre-order的方式,只要left|| right 比root大/小, 就save it作为first/second

Recover Binary Search Tree_第2张图片

看上去好像很对,但是问题非常明显。 当碰到below case的时候,我只把0 keep as first.

然后到了leaf的时候,因为没有left, right 所以不会进行判断,然后就GG了。

Recover Binary Search Tree_第3张图片

所以看起来正确的姿势还是得用In-order Traversal的方法。

发现In-order是第一步,第二步最难的就是

if(first == null && root.val < prev.val)

      first = prev;

if (first!=null && root.val < prev.val)

    second = prev;

这个算法下,first这个东西一确立以后就不会再更改了。 但是second是会更改的,所以我们必须遍历整个Tree。 


下面这个例子,人眼看过去很明显12比1大是ok的,1比10大不ok,10比1小不ok。

Recover Binary Search Tree_第4张图片



这个看过去, 1比5大不ok, 5 比1小不ok, 11比5小不ok,5比11大也不对。

一开始First 定了是11,然后second是5. 看起来很有道理,这两个确实好像被交换了。但是继续遍历发现,1那个node 也不应该比5小啊, 这个时候second就换成了1. 意思是

                  小

         中

把 大和小两个换一下, 中不需要变,整个树的2 swapped 就找到了。



Recover Binary Search Tree_第5张图片



这道题只assume 改了两个node,如果改了更多的话,就会出错。

比如这个:

Recover Binary Search Tree_第6张图片

你可能感兴趣的:(Recover Binary Search Tree)