<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      代碼隨想錄第二十一天 | Leecode 669. 修剪二叉搜索樹、108. 將有序數組轉換為二叉搜索樹、538. 把二叉搜索樹轉換為累加樹

      Leecode 669. 修剪二叉搜索樹

      題目描述

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

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

      • 示例 1:


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

      • 示例 2:


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

      遞歸法解題思路與代碼

      本題要求修剪二叉搜索樹中大于和小于目標區間的節點,最基本的是需要知道二叉搜索樹的性質,其向下投影(中序遍歷)即為有序序列。其次的關鍵在于要對每個節點的可能情形都進行分類討論,此時需要注意不能漏掉某一情形,同時要清晰對于每種情況都要如何操作。首先我們先討論如何來進行分情況討論。

      每個節點的值可能取到的大小0 <= low <= high <= 10^4,同時我們需要保留其中取值在[low, high]閉區間內的值,那么就相當于把數軸劃分為三段,分別為:

      • [0,low),在代碼中可以具體表示為Node->val < low;
      • [low, high],即Node->val >= low && Node->val <= high;
      • (high, 10^4],即Node->val > high

      根據上面的分類情況,就能考慮到每一個節點的所有情況,接下來我們再說明對于其中每一種情況需要如何處理:

      • Node->val < low時,當前節點及其左子樹都不滿足條件,但是右子樹是否滿足還未知。因此可以考慮使用右子節點來替代當前節點,繼續遞歸處理當前節點
      • Node->val >= low && Node->val <= high時,當前節點滿足條件,此時遞歸處理左右子樹
      • Node->val > high時,類似第一種情況,右子樹和當前節點都不滿足,用左子節點來替代當前節點。并再將當前節點傳入遞歸

      根據上面算法思想,即可實現如下代碼:

      class Solution {
      public:
          void cutHelper(TreeNode*& curNode, int low, int high){
              if(!curNode) return; // 如果當前節點已經為空,則直接返回
              if(curNode->val < low) { // 如果當前節點已經小于下界,則用其右子節點來替代當前節點
                  if(curNode->val < low)curNode = curNode->right; // 用右子節點來替代當前節點
                  if(curNode)cutHelper(curNode, low, high); // 繼續將當前節點傳入遞歸修剪(因當前節點已經被替換,所以繼續傳當前節點)
              }
              else if(curNode->val >= low && curNode->val <= high){ // 如果當前節點滿足條件,則需要分別對左右子樹進行修剪
                   cutHelper(curNode->left, low, high); // 遞歸修剪左子樹
                   cutHelper(curNode->right, low, high); // 遞歸修剪右子樹
              }
              else if(curNode->val > high){ // 如果當前節點的值大于上界,則將
                  if(curNode->val > high) curNode = curNode->left; 
                  if(curNode)cutHelper(curNode, low, high);
              }
          }
      
          TreeNode* trimBST(TreeNode* root, int low, int high) {
              cutHelper(root, low, high);
              return root;
          }
      };
      

      上面代碼的最壞時間復雜度為\(O(n)\),即每個節點都需要進行一次判斷,判斷其是否落在區間內。但實際上每次判斷后根據二叉搜索樹的性質,可以知道當前節點左右子樹是否有可能滿足,從而省略一部分判斷用時從而減少時間復雜度。

      Leecode 108. 將有序數組轉換為二叉搜索樹

      題目描述

      給你一個整數數組 nums ,其中元素已經按 升序 排列,請你將其轉換為一棵 平衡 二叉搜索樹。

      • 示例 1:


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

      • 示例 2:


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

      解題思路與代碼展示

      本題是建立二叉樹的題目,此前已經做過幾道類似的題目。關鍵在于劃分數組,以用于建立當前節點的值作為分割點,將數組分為兩半,并后續分別用于遞歸構造左右子樹。本題特別的點在于是需要建立平衡的二叉搜索樹,為了平衡性,我們可以考慮每次使用當前數組的中點作為當前節點的值并對數組進行分割,這樣就可以保證左右子樹中的節點個數只相差1,從而確保了平衡性。

      class Solution {
      public:
          void buildHelper(TreeNode*& curRoot, vector<int> curVec){
              if(curVec.empty()) return; // 如果當前向量已經為空,則直接返回
              int cutPoint = curVec.size()/2 ; // 使用有序數組的中點作為分割點
              curRoot = new TreeNode(curVec[cutPoint]); // 使用中點值來建立當前節點
      
              vector<int> leftVec(curVec.begin(), curVec.begin()+cutPoint); // 建立左子數組
              buildHelper(curRoot->left, leftVec);  // 遞歸建立左子樹
      
              vector<int> rightVec(curVec.begin()+cutPoint+1,curVec.end()); // 建立右子數組
              buildHelper(curRoot->right, rightVec); // 遞歸建立右子樹
      
              return;
          }
      
          TreeNode* sortedArrayToBST(vector<int>& nums) {
              TreeNode* root = nullptr; // 討論空節點的情況
              buildHelper(root, nums); // 調用遞歸函數進行建樹
              return root;
          }
      };
      

      Leecode 538. 把二叉搜索樹轉換為累加樹

      題目描述

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

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

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

      • 示例 1:


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

      遞歸法 解題思路與代碼

      本題使用遞歸來進行深度優先算法。因為要將每個節點轉換為本身與右邊所有節點的和,所以可以知道一開始必須走到最左邊的那個節點并記錄求和值。只要能夠想通深度優先就是中序遍歷,那么本題就沒有什么難度了。直接在中序遍歷遞歸的基礎上,將其更改為記錄求和并更新當前節點的操作即可。故有下面代碼:

      class Solution {
      public:
          void convertHelper(TreeNode* curNode, int& sum){ // 使用中序遍歷來進行遞歸
              if(!curNode) return; // 如果當前節點為空則返回
              convertHelper(curNode->right, sum); // 向右遞歸
      
              sum += curNode->val;  // 將當前節點值加到sum上
              curNode->val = sum;  // 在令當前節點值等于sum
      
              convertHelper(curNode->left, sum); // 向左遞歸
          }
      
          TreeNode* convertBST(TreeNode* root) {
              int sum = 0;
              convertHelper(root, sum);
              return root;
          }
      };
      

      時間復雜度為\(O(n)\),即每個節點遍歷一次。

      今日總結

      實際上是昨日總結...因為本來該4.15發的打卡到了4.16才發,原因是昨天去看了DragonForce北京演出。

      發現二叉樹部分的題目暫時算是刷完了,總的來說感覺大部分題目用遞歸來解決都并不算難,關鍵在于說要去往前、中、后序遍歷的方向去套。以及遞歸中需要分情況討論的地方要把所有可能性都考慮到,那么就基本都能做出來。

      同時還有一個非常重要的點在于,在層序遍歷中使用隊列來解決問題的范式模板,注意當需要分層解決問題的時候,需要固定每一次循環開始時的隊列長度,用于表示當前層的節點個數。

      二叉樹最難的地方感覺就在于,使用迭代來求解的時候,對于前序遍歷和中序遍歷的迭代法需要充分掌握。還有就是當遇到需要自下而上的算法的時候,需要使用回溯的方式。對于回溯算法,如果使用遞歸來實現,使用值傳遞可以免去一次pop出棧操作,但是值傳遞可能會導致每一次遞歸都復制一個棧,當數據量較大時會占用很大的空間。如果使用引用的方式進行回溯,則每次遞歸之后要手動使用pop進行回溯。

      大致上總結了一下最近學到的東西,以及記錄當前力扣進度:

      目前力扣已經79題了,100題盡在眼前,繼續加油

      posted on 2025-04-16 16:51  JQ_Luke  閱讀(471)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 国产91丝袜在线播放动漫| 狠狠色丁香婷婷综合尤物| 国产一级r片内射免费视频| 亚洲精品一区二区三区综合| 狠狠cao日日穞夜夜穞av| 成人网站免费在线观看| 美女裸体黄网站18禁止免费下载| 美女裸体十八禁免费网站| 久久精品夜色噜噜亚洲aa| 精品少妇av蜜臀av| 承德市| 国产老熟女国语免费视频| 婷婷色香五月综合缴缴情香蕉| 亚洲精品日韩在线丰满| 蜜桃久久精品成人无码av| 久久久国产精品樱花网站| 亚洲av无码精品蜜桃| 推特国产午夜福利在线观看| 丰满妇女强制高潮18xxxx| 国产精一区二区黑人巨大| 无套内射视频囯产| 中文午夜乱理片无码| 日韩精品二区三区四区| 国产视频最新| 成人毛片100免费观看| 97人妻中文字幕总站| 少妇又爽又刺激视频| 日韩av毛片福利国产福利| 少妇粉嫩小泬喷水视频www| 久热久热久热久热久热久热 | 亚洲免费一区二区av| 少妇爆乳无码专区| 久久国产乱子精品免费女| 综1合AV在线播放| 午夜一区二区三区视频| 精品偷自拍另类精品在线| 欧美最猛黑人xxxx| 亚洲熟妇少妇任你躁在线观看无码| 亚洲欧美成人一区二区三区| 免费看欧美日韩一区二区三区| 国产成人亚洲欧美二区综合|