[Leetcode] 99. Recover Binary Search Tree 解题报告

来源:互联网 发布:数据恢复视频教程 编辑:程序博客网 时间:2024/05/29 19:32

题目

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?

思路

我们先来看看采用O(n)的空间复杂度的算法会怎么做:对于BST而言,在中序遍历的结果中,节点的值一定是严格有序的,然而当交换了其中两个节点之后,就会出现两个错误的位置。那么这个错误的位置有什么特征,又如何确定呢?

举个例子吧:[1, 2, 3, 4, 5, 6]。如果交换了两个节点之后可能会变成[1, 6, 3, 4, 5, 2]。那么如何找到这两个节点呢?对于第一个数,我们只需要找到第一个比它后面的数大的就可以(在本例中是6)。而被交换到后面的小的数怎么确定呢?它其实就是最后一个比自己前面的数小的数(在本例中是2)。这样思路就比较清楚了:我们采用中序遍历,但是只需要记录两个被错误交换的节点即可。遇到第一个比后面的数字大的节点,就记为first;遇到最后一个比前面的数字小的节点,就记为second,最后交换first和second的值即可。

虽然该算法在代码上看只开辟了O(1)的空间,符合题目要求,但是由于涉及到递归,所以在实际运行过程中,栈所占用的空间复杂度准确来讲是O(logn)。然而O(logn)也是很不错的空间复杂度了,可以近似认为是O(1)。

代码

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    void recoverTree(TreeNode* root) {        TreeNode *last = NULL, *first = NULL, *second = NULL;        inOrderTraverse(root, last, first, second);        swap(first->val, second->val);    }private:    void inOrderTraverse(TreeNode* node, TreeNode* &last, TreeNode* &first, TreeNode* &second) {        if(node == NULL) {            return;        }        inOrderTraverse(node->left, last, first, second);        if(last != NULL && last->val > node->val) {            if(first == NULL) {         // find the first                first = last;            }            second = node;              // update until the last        }        last = node;        inOrderTraverse(node->right, last, first, second);    }};


0 0
原创粉丝点击