day23 | 二叉樹9

0.引言

● 669. 修剪二叉搜索樹
● 108.將有序數(shù)組轉(zhuǎn)換為二叉搜索樹
● 538.把二叉搜索樹轉(zhuǎn)換為累加樹

669. 修剪二叉搜索樹

Category Difficulty Likes Dislikes
algorithms Medium (67.89%) 782 -

給你二叉搜索樹的根節(jié)點(diǎn) root 概耻,同時(shí)給定最小邊界low 和最大邊界 high霜浴。通過(guò)修剪二叉搜索樹,使得所有節(jié)點(diǎn)的值在[low, high]中尸折。修剪樹 不應(yīng)該 改變保留在樹中的元素的相對(duì)結(jié)構(gòu) (即职祷,如果沒(méi)有被移除书聚,原有的父代子代關(guān)系都應(yīng)當(dāng)保留)。 可以證明,存在 唯一的答案 稿存。

所以結(jié)果應(yīng)當(dāng)返回修剪好的二叉搜索樹的新的根節(jié)點(diǎn)。注意瞳秽,根節(jié)點(diǎn)可能會(huì)根據(jù)給定的邊界發(fā)生改變瓣履。

示例 1:

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

示例 2:

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

提示:

  • 樹中節(jié)點(diǎn)數(shù)在范圍 [1, 10<sup>4</sup>] 內(nèi)
  • 0 <= Node.val <= 10<sup>4</sup>
  • 樹中每個(gè)節(jié)點(diǎn)的值都是 唯一
  • 題目數(shù)據(jù)保證輸入是一棵有效的二叉搜索樹
  • 0 <= low <= high <= 10<sup>4</sup>

Discussion | Solution

遞歸法

/*
 * @lc app=leetcode.cn id=669 lang=cpp
 *
 * [669] 修剪二叉搜索樹
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
 public:
  TreeNode* trimBST(TreeNode* root, int low, int high) {
    return dfs(root, low, high);
  }

 private:
  //  后序遍歷
  TreeNode* dfs(TreeNode* node, int low, int high) {
    if (node == nullptr) {
      return nullptr;
    }
    if (node->val < low) {
      return dfs(node->right, low, high);
    }
    if (node->val > high) {
      return dfs(node->left, low, high);
    }
    node->left = dfs(node->left, low, high);
    node->right = dfs(node->right, low, high);
    return node;
  }
};
// @lc code=end

108. 將有序數(shù)組轉(zhuǎn)換為二叉搜索樹

Category Difficulty Likes Dislikes
algorithms Easy (77.34%) 1263 -

給你一個(gè)整數(shù)數(shù)組 nums ,其中元素已經(jīng)按 升序 排列练俐,請(qǐng)你將其轉(zhuǎn)換為一棵 高度平衡 二叉搜索樹袖迎。

**高度平衡 **二叉樹是一棵滿足「每個(gè)節(jié)點(diǎn)的左右兩個(gè)子樹的高度差的絕對(duì)值不超過(guò) 1 」的二叉樹。

示例 1:

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

image.png

示例 2:

image.png
輸入:nums = [1,3]
輸出:[3,1]
解釋:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索樹腺晾。

提示:

  • 1 <= nums.length <= 10<sup>4</sup>
  • -10<sup>4</sup> <= nums[i] <= 10<sup>4</sup>
  • nums嚴(yán)格遞增 順序排列

Discussion | Solution

遞歸法

/*
 * @lc app=leetcode.cn id=108 lang=cpp
 *
 * [108] 將有序數(shù)組轉(zhuǎn)換為二叉搜索樹
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
 public:
  TreeNode* sortedArrayToBST(vector<int>& nums) {
    return dfs(nums);
  }

 private:
  TreeNode* dfs(std::vector<int> nums) {
    if (nums.empty()) {
      return nullptr;
    }
    if (nums.size() == 1) return new TreeNode(nums[0]);
    int mid = nums.size() / 2;

    TreeNode* node = new TreeNode(nums[mid]);

    std::vector<int> left(nums.begin(), nums.begin() + mid);
    std::vector<int> right(nums.begin() + mid + 1, nums.end());

    node->left = dfs(left);
    node->right = dfs(right);
    return node;
  }
};
// @lc code=end

538.把二叉搜索樹轉(zhuǎn)換為累加樹

Category Difficulty Likes Dislikes
algorithms Medium (76.01%) 864 -

給出二叉** 搜索 **樹的根節(jié)點(diǎn)燕锥,該樹的節(jié)點(diǎn)值各不相同,請(qǐng)你將其轉(zhuǎn)換為累加樹(Greater Sum Tree)悯蝉,使每個(gè)節(jié)點(diǎn) node 的新值等于原樹中大于或等于 node.val 的值之和归形。

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

  • 節(jié)點(diǎn)的左子樹僅包含鍵** 小于 **節(jié)點(diǎn)鍵的節(jié)點(diǎn)鼻由。
  • 節(jié)點(diǎn)的右子樹僅包含鍵** 大于** 節(jié)點(diǎn)鍵的節(jié)點(diǎn)暇榴。
  • 左右子樹也必須是二叉搜索樹。

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

示例 1:

image.png
輸入:[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]

提示:

  • 樹中的節(jié)點(diǎn)數(shù)介于 010<sup>4</sup>之間蕉世。
  • 每個(gè)節(jié)點(diǎn)的值介于 -10<sup>4</sup>10<sup>4</sup> 之間蔼紧。
  • 樹中的所有值 互不相同
  • 給定的樹為二叉搜索樹狠轻。

Discussion | Solution

遞歸法

之前還想復(fù)雜了:

/*
 * @lc app=leetcode.cn id=538 lang=cpp
 *
 * [538] 把二叉搜索樹轉(zhuǎn)換為累加樹
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
 public:
  TreeNode* convertBST(TreeNode* root) {
    if (root == nullptr) return nullptr;
    int cumulate_val = 0;
    bool is_right_most = false;
    dfs(root, cumulate_val, is_right_most);
    return root;
  }

 private:
  // 右中左的遍歷順序
  void dfs(TreeNode* node, int& cumulate_val, bool& is_right_most) {
    // 找到最右邊那個(gè)
    if (node->left == nullptr && node->right == nullptr && !is_right_most) {
       is_right_most = true;
       cumulate_val = node->val;
       return;
     }
    // 正常的終止條件
    // if (node->left == nullptr && node->right == nullptr) {
    //   node->val += cumulate_val;
    //   cumulate_val = node->val;
    //   return;
    // }
    if(node==nullptr) return;
    if (node->right) dfs(node->right, cumulate_val, is_right_most);
    node->val += cumulate_val;
    cumulate_val = node->val;
    if (node->left) dfs(node->left, cumulate_val, is_right_most);
  }
};
// @lc code=end

這種情況歉井,[2,1]這種case過(guò)不了,其實(shí)完全不用人為的去找哈误,由于遍歷順序決定哩至,天然的就會(huì)去找到起始的位置:

/*
 * @lc app=leetcode.cn id=538 lang=cpp
 *
 * [538] 把二叉搜索樹轉(zhuǎn)換為累加樹
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
 public:
  TreeNode* convertBST(TreeNode* root) {
    if (root == nullptr) return nullptr;
    int cumulate_val = 0;
    bool is_right_most = false;
    dfs(root, cumulate_val);
    return root;
  }

 private:
  // 右中左的遍歷順序
  void dfs(TreeNode* node, int& cumulate_val) {
    if(node==nullptr) return;
    dfs(node->right, cumulate_val);
    node->val += cumulate_val;
    cumulate_val = node->val;
    dfs(node->left, cumulate_val);
  }
};
// @lc code=end
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蜜自,隨后出現(xiàn)的幾起案子菩貌,更是在濱河造成了極大的恐慌,老刑警劉巖重荠,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箭阶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)仇参,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門嘹叫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人诈乒,你說(shuō)我怎么就攤上這事罩扇。” “怎么了怕磨?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵喂饥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我肠鲫,道長(zhǎng)员帮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任导饲,我火速辦了婚禮捞高,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渣锦。我一直安慰自己棠枉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布泡挺。 她就那樣靜靜地躺著,像睡著了一般命浴。 火紅的嫁衣襯著肌膚如雪娄猫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天生闲,我揣著相機(jī)與錄音媳溺,去河邊找鬼。 笑死碍讯,一個(gè)胖子當(dāng)著我的面吹牛悬蔽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捉兴,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蝎困,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了倍啥?” 一聲冷哼從身側(cè)響起禾乘,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虽缕,沒(méi)想到半個(gè)月后始藕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年伍派,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了江耀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诉植,死狀恐怖祥国,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倍踪,我是刑警寧澤系宫,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站建车,受9級(jí)特大地震影響扩借,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缤至,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一潮罪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧领斥,春花似錦嫉到、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至嚼黔,卻和暖如春细层,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唬涧。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工疫赎, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碎节。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓捧搞,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親狮荔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子胎撇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容