Recover Binary Search Tree BST找乱序的两个元素 @LeetCode

来源:互联网 发布:centos 6删除防火墙 编辑:程序博客网 时间:2024/05/16 19:29

很巧妙的一题,http://yucoding.blogspot.com/2013/03/leetcode-question-75-recover-binary.html  解释的很详细。

tricky的地方在于要注意只有两个元素的情况


package Level4;import Utility.TreeNode;/** * 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?confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.OJ's Binary Tree Serialization:The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.Here's an example:   1  / \ 2   3    /   4    \     5The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". * */public class S99 {public static void main(String[] args) {}TreeNode pre;// 指向当前遍历元素的前一个TreeNode first;// 第一个乱序的元素TreeNode second;// 第二个乱序的元素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;// 第二个乱序的元素。如果用了else,则无法通过只有两个元素的情况}pre = root;// 继续搜索}inorder(root.right);}public void recoverTree(TreeNode root) {pre = null;// 必须在这里初始化一遍,否则OJ会报错first = null;second = null;        inorder(root);        if(first!=null && second!=null){// 只需要交换元素值,而没必要进行指针操作!        int tmp = first.val;        first.val = second.val;        second.val = tmp;        }    }}



具体的思路,还是通过中序遍历,只不过,不需要存储每个节点,只需要存一个前驱即可。

例如1,4,3,2,5,6

1.当我们读到4的时候,发现是正序的,不做处理

2.但是遇到3时,发现逆序,将4存为第一个错误节点,3存为第二个错误节点

3.继续往后,发现3,2又是逆序了,那么将第2个错误节点更新为2

如果是这样的序列:1,4,3,5,6同上,得到逆序的两个节点为4和3。

同理对于边界情况也是可以处理的,例如2,1


/** * Definition for binary tree * public class TreeNode { *     int val; *     TreeNode left; *     TreeNode right; *     TreeNode(int x) { val = x; } * } */public class Solution {        TreeNode first = null, second = null, pre = null;        public void recoverTree(TreeNode root) {        find(root);        swap(first, second);    }        public void find(TreeNode root) {        if(root == null) {            return;        }                find(root.left);                if(pre == null) {       // initialize pre in the very beginning            pre = root;        } else{            if(pre.val > root.val){     // out of order                if(first == null) {     // first time                    first = pre;                    second = root;                } else {                // second time                    second = root;                }            }            pre = root;         // update pre to current node        }                 find(root.right);    }        // swap binary tree node    public void swap(TreeNode a, TreeNode b) {        int tmp = a.val;        a.val = b.val;        b.val = tmp;    }}



http://huntfor.iteye.com/blog/2077665