这是一道好题,思路虽然有,但是提交之后总是有数据过不了,又按照数据改改改,最后代码都没法看了。收到的教训是如果必须为自己的代码加上很多很多特殊的限定,来过一些特殊的数据的话,说明代码本身有很大的漏洞。
这道题,我想到了要用两个指针保存乱序的节点,甚至想到了用一个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; } };
leetcode第一刷_Recover Binary Search Tree
时间: 2024-10-29 19:09:44