LeetCode99 恢復二叉搜尋樹

2021-10-08 22:53:26 字數 2164 閱讀 9874

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

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

樹節點的定義

/**

* 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 空間複雜度的解法很容易實現。你能想出乙個只使用常數空間的解決方案嗎?題目要求的是二叉搜尋樹,二叉搜尋樹有乙個特點,那就是有序,所以我們可以得知在中序遍歷二叉搜尋樹得到的序列是遞增...