Leetcode:99.恢復二叉搜尋樹
阿新 • • 發佈:2018-11-13
二叉搜尋樹中的兩個節點被錯誤地交換。請在不改變其結構的情況下,恢復這棵樹。
示例 1:
輸入: [1,3,null,null,2] 1 / 3 \ 2 輸出: [3,1,null,null,2] 3 / 1 \ 2
示例 2:
輸入: [3,1,4,null,null,2] 3 / \ 1 4 / 2 輸出: [2,1,4,null,null,3] 2 / \ 1 4 / 3
解題思路:
二叉搜尋樹:中序遍歷中沒有逆序對。如果知道什麼是中序遍歷,還有二叉搜尋樹,本題只能算是easy。
按照題意只交換了二叉樹的兩個結點,這也就意味著是排序陣列中交換了兩個元素的位置,這麼一想就會變得容易很多。
1. 交換的兩個元素中序遍歷相鄰。這時只會出現一個逆序對,交換兩個逆序對結點的的val即可。
2. 兩個元素在中序遍歷陣列中不相鄰。會出現兩個逆序對,我們只需記錄第一個逆序對的第一個結點,以及第二個逆序對的第二個結點即可,最後交換兩個結點的val即可。
只需要記錄逆序對的位置即可,因此僅用了常數個空間。
#define hasLChild(x) (!(x->left==NULL)) #define hasRChild(x) (!(x->right==NULL)) class Solution { public: void recoverTree(TreeNode* root) { //中序遍歷 In_order_traversal(root); swap(first->val, second->val); } void In_order_traversal(TreeNode* root) { if (sgn == 2) return; if (hasLChild(root)) In_order_traversal(root->left); if (temp == NULL) temp = root; else { if (temp->val > root->val) {//出現了逆序對 if (sgn == 0) { first = temp; second = root; sgn = 1; } else { second = root; sgn = 2; } } temp = root; } if (hasRChild(root)) In_order_traversal(root->right); } private: TreeNode* temp = NULL; TreeNode* first, *second; int sgn = 0; }; |