这是一道好题,思路尽管有,可是提交之后总是有数据过不了,又依照数据改改改。最后代码都没法看了。收到的教训是假设必须为自己的代码加上非常多非常多特殊的限定。来过一些特殊的数据的话。说明代码本身有非常大的漏洞。
这道题,我想到了要用两个指针保存乱序的节点,甚至想到了用一个pre指针来保存前面一个节点,可是问题出在哪里呢?我认为应该是自己对树的遍历理解的不够深刻。既然知道了二叉搜索树一定是用中序遍历的,那么程序的框架应该立即写的出来,先左子树,再根,再右子树,那你说什么时候更新pre指针呢,当然是訪问根节点的时候。假设把每次返回的节点作为接下来考虑的左子树,事实上并非一种中序遍历,更像是前序遍历。另一点,我当时总是想单独的找出这两个乱序的节点,然后加了非常多特殊情况考虑假设他们两个相邻怎么办。事实上这不是非常好解决的吗,由于一共仅仅有两个节点乱掉了,那么一開始不满足条件的那对节点肯定包括了当中一个,并且是较大的那个是乱掉的。往后的话,假设又出现了这个问题,一定是较小那个,不用加不论什么特殊情况的考虑。
代码很简洁,好羞愧:
TreeNode *e1, *e2, *pre;
void inorder(TreeNode *root){if(root == NULL) return;if(root->left)inorder(root->left);if(pre&&pre->val>root->val){if(e1 == NULL) e1 = pre, e2 = root;else e2 = root;}pre = root;if(root->right)inorder(root->right);return;
} class Solution {
public:void recoverTree(TreeNode *root) {pre = NULL, e1 = NULL, e2 = NULL;inorder(root);swap(e1->val, e2->val);return;}
};