打卡第二十四天 恢復二叉搜尋樹

2021-10-04 09:07:46 字數 3663 閱讀 7557

方法一:對陣列進行排序

演算法:

按中序遍歷樹,遍歷之後的陣列應該是幾乎排序的列表,其中只有兩個元素被交換

再次遍歷樹,將值x的節點改為y,將值y的節點改為x

**:

/**

* definition for a binary tree node.

* public class treenode

* }*/class

solution

public

int[

](list

nums)

}return

newint

;}public

void

recover

(treenode r,

int count,

int x,

int y)

recover

(r.left, count, x, y)

;recover

(r.right, count, x, y);}

}public

void

recovertree

(treenode root)

}

執行結果:

複製到分析:

時間複雜度:最壞o(n),最好o(1)

空間複雜度:o(n)

優化思路:

在方法一中,我們討論了這個難題的三個簡單子問題:

構造中序遍歷序列

在幾乎排序的數列中查詢兩個交換的元素

在陣列中交換兩個節點的值

事實上,我們可以將上面的三個步驟簡化成兩步:

合併步驟一和步驟二,即在中序遍歷時確定交換的元素

交換節點的值

以下的方法區別只在於實現中序遍歷的演算法

方法二:迭代中序遍歷

演算法:

在這裡,我們通過迭代構造中序遍歷,並在一次遍歷中找到交換的節點。

迭代順序很簡單:盡可能的向左走,然後向右走一步,重複一直到結束。

若要找到交換的節點,就記錄中序遍歷中的最後乙個節點 pred(即當前節點的前置節點),並與當前節點的值進行比較。如果當前節點的值小於前置節點 pred 的值,說明該節點是交換節點之一。

交換的節點只有兩個,因此在確定了第二個交換節點以後,可以終止遍歷。

這樣,就可以直接獲取節點(而不僅僅是它們的值),從而實現 o(1)的交換時間,大大減少了步驟 3 所需的時間。

**:

/**

* definition for a binary tree node.

* public class treenode

* }*/class

solution

public

void

recovertree

(treenode root)

root = stack.

removelast()

;if(pred != null && root.val < pred.val)

pred = root;

root = root.right;

}swap

(x, y);}

}

執行結果:

複雜度分析:

時間複雜度:最好o(1),最壞(交換節點之一是最右邊的葉節點)o(n)

空間複雜度:o(h),h指的是樹的高度

方法三:遞迴中序遍歷

演算法:

遵循 left 到 node 到 right 方向

即對左子節點進行遞迴呼叫,然後判斷該節點是否被交換,再對右子節點執行遞迴呼叫

**:

/**

* definition for a binary tree node.

* public class treenode

* }*/class

solution

public

void

(treenode root)

pred = root;

(root.right);}

public

void

recovertree

(treenode root)

}

執行結果:

複雜度分析:

時間複雜度:最好o(1),最壞o(n)

空間複雜度:o(h)

方法四:mirris中序遍歷

演算法:如果沒有鏈結,設定連線並走向左子樹。

如果有連線,斷開連線並走向右子樹。

如果該節點沒有左孩子,即沒有左子樹,則我們直接走向右子樹。

**:

/**

* definition for a binary tree node.

* public class treenode

* }*/class

solution

public

void

recovertree

(treenode root)

// break link predecessor.right = root

// link is broken : time to change subtree and go right

else

pred = root;

predecessor.right = null;

root = root.right;}}

// if there is no left child

// then just go right.

else

pred = root;

root = root.right;}}

swap

(x, y);}

}

執行結果:

複雜度分析:

時間複雜度:o(n),訪問每個節點兩次

空間複雜度:o(1)

吾之生也有涯,而知也無涯

冥想第二十四天

還有乙個需要提高的地方就是 慢一點,以往自己對成功和只是追求的太急切。一急切就亂了節奏,適當的急切是必要的 放輕鬆全身都是最舒服的狀態。平靜的內心讓自己能面對生活的困難。感謝自己,感謝家人,感謝朋友,感謝一切。不責怪自己,一天比一天進步就好。慢慢來。下午和客戶積極的溝通,全身心的投入,發現一點也不困...

連續總結第二十四天

11.4 康鑫 連續總結第二十四天 今天學習了課本上有關陣列的知識,陣列與指標。1,指標運算包括a,賦值運算 b,算術運算 c,關係運算 d,邏輯運算。2 一維陣列 a 與指標 p 3,二維陣列 b,m行n列 與指標。4,字元陣列 s 與指標 ps 5,指標陣列 完成了課本的例題,通過程式設計實現二...

2017 8 23暑假集訓第二十四天

今天一共a了兩道題 1001.1002 比較簡單的?1001做了一上午 一直在繞一點 當輸入字元m後,要輸入五個數字 用scanf輸入的 但是!卻只寫了四個 d!然後就一直在找bug!找了一上午。我很疑惑,為什麼編譯能過!提交還是莫名其妙的wa!一直在懷疑自己!下午 睡過頭了 來的晚了 1007看了...