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...
我做的时候大概知道要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
看上去好像很对,但是问题非常明显。 当碰到below case的时候,我只把0 keep as first.
然后到了leaf的时候,因为没有left, right 所以不会进行判断,然后就GG了。
所以看起来正确的姿势还是得用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。
这个看过去, 1比5大不ok, 5 比1小不ok, 11比5小不ok,5比11大也不对。
一开始First 定了是11,然后second是5. 看起来很有道理,这两个确实好像被交换了。但是继续遍历发现,1那个node 也不应该比5小啊, 这个时候second就换成了1. 意思是
小
中
大
把 大和小两个换一下, 中不需要变,整个树的2 swapped 就找到了。
这道题只assume 改了两个node,如果改了更多的话,就会出错。
比如这个: