程式碼隨想錄演算法訓練營day23 | leetcode 669. 修剪二叉搜尋樹、108. 將有序陣列轉換為二叉搜尋樹、538. 把二叉搜尋樹轉換為累加樹

Humphreyr發表於2024-03-14

目錄
  • 題目連結:669. 修剪二叉搜尋樹-中等
  • 題目連結:108. 將有序陣列轉換為二叉搜尋樹-簡單
  • 題目連結:538. 把二叉搜尋樹轉換為累加樹-中等

題目連結:669. 修剪二叉搜尋樹-中等

題目描述:

給你二叉搜尋樹的根節點 root ,同時給定最小邊界low 和最大邊界 high。透過修剪二叉搜尋樹,使得所有節點的值在[low, high]中。修剪樹 不應該 改變保留在樹中的元素的相對結構 (即,如果沒有被移除,原有的父代子代關係都應當保留)。 可以證明,存在 唯一的答案

所以結果應當返回修剪好的二叉搜尋樹的新的根節點。注意,根節點可能會根據給定的邊界發生改變。

示例 1:

img

輸入:root = [1,0,2], low = 1, high = 2
輸出:[1,null,2]

示例 2:

img

輸入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
輸出:[3,2,null,1]

提示:

  • 樹中節點數在範圍 [1, 10^4]
  • 0 <= Node.val <= 10^4
  • 樹中每個節點的值都是 唯一
  • 題目資料保證輸入是一棵有效的二叉搜尋樹
  • 0 <= low <= high <= 10^4

在判斷完當前節點後,還需要繼續遞迴地判斷該節點左(右)子樹的左右子樹

程式碼如下:

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(root == NULL) return NULL;
        if(root->val < low) return trimBST(root->right, low, high);
        if(root->val > high) return trimBST(root->left, low, high);
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
        return root;
    }
};

題目連結:108. 將有序陣列轉換為二叉搜尋樹-簡單

題目描述:

給你一個整數陣列 nums ,其中元素已經按 升序 排列,請你將其轉換為一棵

平衡

二叉搜尋樹。

示例 1:

img

輸入:nums = [-10,-3,0,5,9]
輸出:[0,-3,9,-10,null,5]
解釋:[0,-10,5,null,-3,null,9] 也將被視為正確答案:

示例 2:

img

輸入:nums = [1,3]
輸出:[3,1]
解釋:[1,null,3] 和 [3,1] 都是高度平衡二叉搜尋樹。

提示:

  • 1 <= nums.length <= 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums嚴格遞增 順序排列

這裡按照左閉右開原則

程式碼如下:

class Solution {
public:
    TreeNode* create(vector<int>& nums, int lIndex, int rIndex) {
        if (lIndex >= rIndex)
            return NULL;
        int mid = lIndex + (rIndex - lIndex) / 2;
        TreeNode* cur = new TreeNode(nums[mid]);
        cur->left = create(nums, lIndex, mid);
        cur->right = create(nums, mid + 1, rIndex);
        return cur;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return create(nums, 0, nums.size());
    }
};

題目連結:538. 把二叉搜尋樹轉換為累加樹-中等

題目描述:

給出二叉 搜尋 樹的根節點,該樹的節點值各不相同,請你將其轉換為累加樹(Greater Sum Tree),使每個節點 node 的新值等於原樹中大於或等於 node.val 的值之和。

提醒一下,二叉搜尋樹滿足下列約束條件:

  • 節點的左子樹僅包含鍵 小於 節點鍵的節點。
  • 節點的右子樹僅包含鍵 大於 節點鍵的節點。
  • 左右子樹也必須是二叉搜尋樹。

注意:本題和 1038: https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/ 相同

示例 1:

img

輸入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
輸出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

示例 2:

輸入:root = [0,null,1]
輸出:[1,null,1]

示例 3:

輸入:root = [1,0,2]
輸出:[3,3,2]

示例 4:

輸入:root = [3,2,4,1]
輸出:[7,9,4,10]

提示:

  • 樹中的節點數介於 010^4 之間。
  • 每個節點的值介於 -10^410^4 之間。
  • 樹中的所有值 互不相同
  • 給定的樹為二叉搜尋樹。

這道題與之前的雙指標法類似,這裡是定義前驅節點,記錄前驅節點的值也行

程式碼如下:

class Solution {
public:
    TreeNode* post;
    void traversal(TreeNode* root) {
        if (root == NULL)
            return;
        traversal(root->right);
        if (post != NULL)
            root->val += post->val;
        post = root;
        traversal(root->left);
    }
    TreeNode* convertBST(TreeNode* root) {
        traversal(root);
        return root;
    }
};

相關文章