99 恢復二叉搜尋樹

2021-10-08 22:41:02 字數 2886 閱讀 9801

二叉搜尋樹中的兩個節點被錯誤地交換。

請在不改變其結構的情況下,恢復這棵樹。

二叉搜尋樹中序遍歷為有序陣列,如[1, 2, 3, 4, 5, 6],交換其中不相鄰任兩個,變成[1, 6, 3, 4, 5, 2]會有兩個逆序對[6, 3]和[5, 2],可以看出交換位置為前一逆序對的前乙個元素和後一逆序對的後一元素。相鄰的話只有乙個逆序對。

中序遍歷然後儲存在陣列中,在陣列中找出要交換的元素值x,y,然後再遍歷樹修改值即可。

/**

* definition for a binary tree node.

* struct treenode

* treenode(int x) : val(x), left(nullptr), right(nullptr) {}

* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}

* };

*/class

solution

} pair<

int,

int>

findswap

(const vector<

int>

& ans)

else}}

return;}

void

recover

(treenode* root,

int count,

int x,

int y)

}recover

(root -

> left, count, x, y)

;recover

(root -

> right, count, x, y);}

}void

recovertree

(treenode* root)

};

其實就是省去ans陣列的空間,注意到其實我們只需要比較當前訪問節點和前一訪問節點的大小資訊,就可以知道了待交換節點了。使用迭代方法進行中序遍歷,需要乙個棧來作為輔助陣列,儲存前節點資訊即可。

/**

* definition for a binary tree node.

* struct treenode

* treenode(int x) : val(x), left(nullptr), right(nullptr) {}

* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}

* };

*/class

solution

stack> s;

treenode* x =

nullptr

; treenode* y =

nullptr

; treenode* pre =

nullptr

;while

(!s.

empty()

|| root !=

nullptr

) root = s.

top();

s.pop();

if(pre !=

nullptr

)else}}

pre = root;

root = root -

> right;

}swap

(x -

> val, y -

> val);}

};

morris中序遍曆法可以將非遞迴中序遍歷空間複雜度降為o(1),但是時間複雜度會上公升到o(2n)。

步驟(假定當前遍歷到的節點為x):

morris中序遍歷的訪問節點情況出現在當前節點沒有左孩子節點時和當前節點的前驅節點指向當前節點時,前面一種情況說明該節點必須輸出了(中序遍歷的定義),後面一種情況說明當前節點已經被第二次訪問,說明當前節點的左子樹已經訪問完畢了,需要輸出當前節點了。

回到該題,所以我們只需在上述兩種該輸出情況中,比較pre節點和當前節點的值即可。

/**

* definition for a binary tree node.

* struct treenode

* treenode(int x) : val(x), left(nullptr), right(nullptr) {}

* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}

* };

*/class

solution

//最右節點右孩子為空,設定指向當前節點,同時前進

if(predecessor -

> right ==

nullptr

)//最右節點右孩子為當前節點,說明左子樹訪問完畢,輸出當前節點,前進右孩子節點

else}}

pre = root;

predecessor -

> right =

nullptr

; root = root -

> right;}}

//當前節點沒有左孩子節點,輸出當前節點,直接前進右孩子節點,

else}}

pre = root;

root = root -

> right;}}

swap

(x -

> val, y -

> val);}

};

99 恢復二叉搜尋樹

二叉搜尋樹中的兩個節點被錯誤地交換。請在不改變其結構的情況下,恢復這棵樹。示例 2 輸入 3,1,4,null,null,2 3 1 4 2輸出 2,1,4,null,null,3 2 1 4 3高階 使用 o n 空間複雜度的解法很容易實現。你能想出乙個只使用常數空間的解決方案嗎?在二叉搜尋樹中,...

99 恢復二叉搜尋樹

二叉搜尋樹中的兩個節點被錯誤地交換。請在不改變其結構的情況下,恢復這棵樹。示例 1 輸入 1,3,null,null,2 1 3 2輸出 3,1,null,null,2 3 1 2分析 1.假如乙個bst中序是4,2,3,1,我們發現要交換1和4,找到1和4並交換即可,通過觀察發現,第乙個要交換的節...

99 恢復二叉搜尋樹

二叉搜尋樹中的兩個節點被錯誤地交換。請在不改變其結構的情況下,恢復這棵樹。示例 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...