1. 程式人生 > >leetcode450. 刪除二叉搜尋樹中的節點

leetcode450. 刪除二叉搜尋樹中的節點

題目

給定一個二叉搜尋樹的根節點 root 和一個值 key,刪除二叉搜尋樹中的 key 對應的節點,並保證二叉搜尋樹的性質不變。返回二叉搜尋樹(有可能被更新)的根節點的引用。

一般來說,刪除節點可分為兩個步驟:

首先找到需要刪除的節點;
如果找到了,刪除它。
說明: 要求演算法時間複雜度為 O(h),h 為樹的高度。

示例:

root = [5,3,6,2,4,null,7]
key = 3

    5
   / \
  3   6
 / \   \
2   4   7

給定需要刪除的節點值是 3,所以我們首先找到 3 這個節點,然後刪除它。

一個正確的答案是 [5,4,6,2,null,null,7], 如下圖所示。

    5
   / \
  4   6
 /     \
2       7

另一個正確答案是 [5,2,6,null,4,null,7]。

    5
   / \
  2   6
   \   \
    4   7

解題

/**
 * 450. 刪除二叉搜尋樹中的節點
 */
class Solution {
    /**
     * 在以root為根節點的二分搜尋樹中刪除節點key
     * @param root
     * @param key
     * @return 返回刪除後新的根節點
     */
    public TreeNode deleteNode(TreeNode root, int key)
{ if (root == null) { return null; } if (key > root.val) { // key大於當前節點, 從右子樹刪除節點key, 返回刪除節點key後新的根節點 root.right = deleteNode(root.right, key); return root; } else if (key < root.val) { // key小於當前節點, 從左子樹刪除節點key, 返回刪除節點key後新的根節點
root.left = deleteNode(root.left, key); return root; } else { // 左子樹為空的情況 if (root.left == null) { return root.right; } // 右子樹為空的情況 if (root.right == null) { return root.left; } // 左右子樹都不為空的情況 // 從右子樹查詢當前節點的後繼節點 TreeNode successor = findMin(root.right); // 在右子樹中刪除後繼節點 successor.right = deleteMin(root.right); successor.left = root.left; root.left = root.right = null; return successor; } } /** * 查詢以root為根節點的二分搜尋樹中的最小值, 用於刪除節點時查詢後繼元素 * @param root * @return 返回 */ private TreeNode findMin(TreeNode root){ if (root.left != null) { return findMin(root.left); } return root; } /** * 刪除root為根節點的二分搜尋樹中的最小值 * @param root * @return 返回刪除節點後的樹的根節點 */ private TreeNode deleteMin(TreeNode root){ if (root.left != null) { root.left = deleteMin(root.left); return root; } return root.right; } }