问题:
给定一颗BST(二叉搜索树),其中存在两个节点顺序颠倒,请找出他们,并恢复正确次序。
Example 1: Input: root = [1,3,null,null,2] Output: [3,1,null,null,2] Explanation: 3 cannot be a left child of 1 because 3 > 1. Swapping 1 and 3 makes the BST valid. Example 2: Input: root = [3,1,4,null,null,2] Output: [2,1,4,null,null,3] Explanation: 2 cannot be in the right subtree of 3 because 2 < 3. Swapping 2 and 3 makes the BST valid. Constraints: The number of nodes in the tree is in the range [2, 1000]. -231 <= Node.val <= 231 - 1
解法:Binary Search Tree(二叉搜索树)inorder traverse(中序遍历)
由于是BST,
可知,中序遍历+排序(从小到大)-> BST
因此,我们同样通过中序遍历,来寻找有问题的两个节点。
步骤:
1. 递归中序遍历二叉树
2. 找到问题节点first和second
1. 对于每个当前节点node,我们需要判定:如果 node->val < pre->val ,那么当前节点和pre节点,一定存在一个节点不正确。
(pre节点为遍历的前一个节点,每次处理完毕更新pre=当前node)
2. 而我们要找的first和second,具有如下特点:
1. first:最左边不正确的节点。
而对于中序遍历过程中,第一次保存的有问题的pre,则为first。
2. second:最右边不正确的节点。
而对于中序遍历过程中,有问题的当前节点node(到目前为止,最后一个遍历到的节点),则为second。
3. 交换二者的val
代码参考:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 * }; 11 */ 12 class Solution { 13 public: 14 TreeNode* first = nullptr, * second = nullptr; 15 TreeNode* pre = nullptr; 16 //inorder traverse the tree, 17 //to find the mistake two node: first & second 18 // for each current node: judge if (pre->val > node->val) (wrong order) 19 // (pre: update pre = node in each processing end.) 20 // ->first: the leftest node which is in wrong order. 21 // (if first has been assigned, in inorder traverse-> already find the leftest node.) 22 // ->second: the rightest node which is in wrong order. 23 // (for each process, current node is the rightest node so far.) 24 //swap these two node 25 void recoverTree(TreeNode* root) { 26 traverse(root); 27 swap(first->val, second->val); 28 } 29 void traverse(TreeNode* node) { 30 if(!node) return; 31 //inorder traverse(BST left<root<right) 32 //1.left 33 traverse(node->left); 34 //2.current node 35 if(pre && pre->val > node->val) { 36 if(!first) first = pre; 37 second = node; 38 } 39 pre = node; 40 //3.right 41 traverse(node->right); 42 } 43 };