二叉搜尋樹中的兩個節點被錯誤地交換。
請在不改變其結構的情況下,恢復這棵樹。
示例 2:
輸入: [3,1,4,null,null,2]3/
1 4/
2輸出: [2,1,4,null,null,3]
2/ \
1 4/
3高階:
使用 o(n) 空間複雜度的解法很容易實現。
你能想出乙個只使用常數空間的解決方案嗎?
在二叉搜尋樹中,給定節點的左子樹中的節點要小於他,其右子樹的節點要大於給定節點。二叉搜尋樹的中序遍歷一定是單調遞增的。
這道題的關鍵是找到那兩個節點,然後進行交換
第乙個節firstnode點,是第乙個按照中序遍歷時候前乙個節點大於後乙個節點,我們選取前乙個節點,這裡指節點4;
第二個節點secondnode,是在第乙個節點找到之後, 後面出現前乙個節點大於後乙個節點,我們選擇後乙個節點,這裡指節點1;
當兩個節點相鄰時,firstnode就是前乙個數,secondnode就是後乙個數。
解法一:
中序遍歷時使用棧將樹的節點儲存起來
# @lc code=start
# definition for a binary tree node.
# class treenode:
# def __init__(self, x):
# self.val = x
# self.left = none
# self.right = none
class
solution
:def
recovertree
(self, root: treenode)
->
none
:"""
do not return anything, modify root in-place instead.
"""# 構建兩個指標
# 第乙個節點,是第乙個按照中序遍歷時候前乙個節點大於後乙個節點,我們選取前乙個節點
# 第二個節點,是在第乙個節點找到之後, 後面出現前乙個節點大於後乙個節點,我們選擇後乙個節點
firstnode =
none
secondnode =
none
pre = treenode(
float
("-inf"))
stack =
p = root
while p or stack:
while p:
p = p.left
p = stack.pop(
)# 當找到第乙個節點之後,firstnode就不變了
# 在第乙個節點處,firstnode等於前乙個節點的值,secondnode等於後乙個節點的值
# 所以在要交換的兩個節點相鄰時也滿足條件
# if
not firstnode and pre.val>p.val:
firstnode = pre
# 第二個節點, 是在第乙個節點找到之後, 後面出現前乙個節點大於後乙個節點,我們選擇後乙個節點
if firstnode and pre.val>p.val:
secondnode = p
pre = p
p = p.right
firstnode.val, secondnode.val = secondnode.val, firstnode.val
解法二:
使用莫里斯遍歷,讓部分下層的空指標指向上層
# definition for a binary tree node.
# class treenode:
# def __init__(self, x):
# self.val = x
# self.left = none
# self.right = none
class
solution
:def
recovertree
(self, root: treenode)
->
none
: firstnode =
none
secondnode =
none
pre = treenode(
float
("-inf"))
currrent = root
nxt =
none
while currrent!=
none
: nxt = currrent.left
if nxt!=
none
:while nxt.right!=
none
and nxt.right!=currrent:
# 尋找左子樹的最右節點
nxt = nxt.right
# 如果最右節點的右節點是none,將其指向當前這部分子樹的根節點
if nxt.right==
none
: nxt.right = currrent
currrent = currrent.left
continue
else
: nxt.right =
none
# 確定兩個指標
ifnot firstnode and pre.val>currrent.val:
firstnode = pre
if firstnode and pre.val>currrent.val:
secondnode = currrent
# 直到到達最左邊的節子點
pre = currrent
currrent = currrent.right # 遍歷右子樹
firstnode.val, secondnode.val = secondnode.val, firstnode.val
解法三:先中序遍歷一次得到所有的值,再對其進行排序,然後再進行一次中序遍歷將排序後的值賦給每個節點
# definition for a binary tree node.
# class treenode:
# def __init__(self, x):
# self.val = x
# self.left = none
# self.right = none
class
solution
:def
__init__
(self)
: self.val_list =
self.index =
0def
recovertree
(self, root: treenode)
->
none
: p = root
self.inorder(p)
# 先中序遍歷一次
self.val_list.sort(
)# 對遍歷得到的值進行排序
self.getorder(root)
# 將排序後的值賦給每乙個節點
# 中序遍歷一次,得到所有的值
definorder
(self, root)
:if root!=
none
: self.inorder(root.left)
self.inorder(root.right)
# 再次中序遍歷,給每個節點賦值
defgetorder
(self, root)
:if root!=
none
: self.getorder(root.left)
root.val = self.val_list[self.index]
self.index +=
1 self.getorder(root.right)
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,2,3,4,5,6 交換其中不相鄰任兩個,變成 1,6,3,4,5,2 會有兩個逆序對 6,3 和 5,2 可以看出交換位置為前一逆序對的前乙個元素和後一逆序對的後一元素。相鄰的話只有乙個...
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...