二叉搜尋樹中的兩個節點被錯誤地交換。
請在不改變其結構的情況下,恢復這棵樹。
樹節點的定義
/**
* definition for a binary tree node.
* public class treenode
* treenode(int val)
* treenode(int val, treenode left, treenode right)
* }*/
方法一
o(n)的空間複雜度,o(n)的時間複雜度,用中序遍歷,遍歷出的節點插入佇列,之後在佇列中尋找出錯的兩個節點。
注意:引入flag標誌位,是為了消除兩個互換位置的節點是佇列中前後兩個的關係
class
solution
if(flag ==1)
} pre = cur;
}int temp = l.val;
l.val = r.val;
r.val = temp;
}public
void
helper
(treenode root)
}
方法二:
空間複雜度是o(1),不用額外存放節點,根據方法一改進而來,在中序遍歷的過程中找到兩個節點,找到第二個節點之後剪枝。
class
solution
pre = prenode.val;
helper
(root)
;int temp = l.val;
l.val = r.val;
r.val = temp;
}//中序遍歷
public
void
helper
(treenode root)
else
} pre = cur;
prenode = root;
helper
(root.right);}
}
方法三:morris 中序遍歷
morris 遍歷演算法整體步驟如下(假設當前遍歷到的節點為 xx):
如果 x 無左孩子,則訪問 x 的右孩子,即 x=x.right。
如果 x 有左孩子,則找到 x 左子樹上最右的節點(即左子樹中序遍歷的最後乙個節點,x 在中序遍歷中的前驅節點),我們記為 predecessor。根據 predecessor 的右孩子是否為空,進行如下操作。
(1)如果 predecessor 的右孩子為空,則將其右孩子指向 x,然後訪問 x 的左孩子,即 x=x.left。
(2)如果 predecessor 的右孩子不為空,則此時其右孩子指向 x,說明我們已經遍歷完 x 的左子樹,我們將 predecessor 的右孩子置空,然後訪問 x 的右孩子,即 x = x.right。
重複上述操作,直至訪問完整棵樹。
class
solution
// 讓 predecessor 的右指標指向 root,繼續遍歷左子樹
if(predecessor.right == null)
// 說明左子樹已經訪問完了,我們需要斷開鏈結
else
} pred = root;
predecessor.right = null;
root = root.right;}}
// 如果沒有左孩子,則直接訪問右孩子
else
} pred = root;
root = root.right;}}
swap
(x, y);}
public
void
swap
(treenode x, treenode y)
}
Leetcode99 恢復二叉搜尋樹
第一次寫這個部落格以後我發現我理解錯了題目,但是我的問題更具有一般性,更複雜,所以文章就不改了 題目 只有兩個結點被錯誤的交換。我的 有任意多個結點被錯誤的交換。先分析題目 使用o n 空間複雜度的解法很容易實現,那麼我們先看看很容易實現是怎實現的。1 中序遍歷二叉樹,並將中序序列儲存在乙個陣列nu...
LeetCode 99 恢復二叉搜尋樹
3 1 2示例 2 輸入 3,1,4,null,null,2 3 1 4 2 輸出 2,1,4,null,null,3 2 1 4 3 高階 使用 o n 空間複雜度的解法很容易實現。你能想出乙個只使用常數空間的解決方案嗎?1.中序遍歷,儲存陣列 2.排序陣列 3.重新賦值,恢復二叉樹 includ...
leetcode 99恢復二叉搜尋樹
給你二叉搜尋樹的根節點 root 該樹中的兩個節點被錯誤地交換。請在不改變其結構的情況下,恢復這棵樹。高階 使用 o n 空間複雜度的解法很容易實現。你能想出乙個只使用常數空間的解決方案嗎?題目要求的是二叉搜尋樹,二叉搜尋樹有乙個特點,那就是有序,所以我們可以得知在中序遍歷二叉搜尋樹得到的序列是遞增...