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?
分析:本题做的思路是找到两个需要交换的结点,把两个结点的val值进行交换即可。
以下两种方法都是LeetCode Discuss中的方法:
方法1:用递归或栈的方法对树进行中序遍历,当然这种方法不满足O(1)的空间复杂度
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void recover(TreeNode *root, TreeNode *&pre, TreeNode *&a, TreeNode *&b) { if (root) { recover(root->left, pre, a, b); if (root->val < pre->val) { if (!a) a = pre; //a should change once. b = root; //b could change twice. } pre = root; recover(root->right, pre, a, b); } } void recoverTree(TreeNode *root) { if (!root) return; TreeNode p(numeric_limits<int>::min()); TreeNode *a, *b, *pre; a = b = 0; pre = &p; recover(root, pre, a, b); if (a && b) { swap(a->val, b->val); } return; } };
方法2:morris traversal的方法,这种方法借鉴线索二叉树的方法,即不用递归和栈,用改变树的关键结点的指向的方法来遍历二叉树,使用完指向信息后,再将树恢复。参见http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/
class Solution { public: void recoverTree(TreeNode *root) { if (root == NULL) return; TreeNode * ptr, *pred, * current; TreeNode * pred1, * cur1, * pred2, * cur2; current = root; ptr = pred = NULL; pred1 = cur1 = pred2 = cur2 = NULL; while (current != NULL){ if (current->left == NULL){ pred = current; current = current->right; }else{ ptr = current->left; while (ptr->right != NULL && ptr->right != current) ptr = ptr->right; if (ptr->right == NULL){//构造线索二叉树 ptr->right = current; current = current->left; }else{ //把线索二叉树恢复成原先的二叉树 ptr->right = NULL; pred = current; current = current->right; } }//end if if (pred != NULL && current != NULL && pred->val > current->val){//找到待交换的2个数 if (pred1 == NULL) { pred1 = pred; cur1 = current; } else { pred2 = pred; cur2 = current; } }//end if }//end if int tmp; if (pred1 != NULL && cur2 != NULL){//pred1和cur2交换 tmp = pred1->val; pred1->val = cur2->val; cur2->val = tmp; } else{ //pred1和cur1交换 tmp = pred1->val; pred1->val = cur1->val; cur1->val = tmp; } } };
把原理弄清楚,自己实现一下。