二叉搜索樹題目:將有序數組轉換為二叉搜索樹

文章目錄

  • 題目
    • 標題和出處
    • 難度
    • 題目描述
      • 要求
      • 示例
      • 數據范圍
  • 解法
    • 思路和算法
    • 證明
    • 代碼
    • 復雜度分析

題目

標題和出處

標題:將有序數組轉換為二叉搜索樹

出處:108. 將有序數組轉換為二叉搜索樹

難度

4 級

題目描述

要求

給定整數數組 nums \texttt{nums} nums,其中元素已經按升序排列,將其轉換為高度平衡二叉搜索樹。

高度平衡二叉樹滿足每個結點的左右子樹的高度差的絕對值不超過 1 \texttt{1} 1

示例

示例 1:

示例 1.1

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

示例 1.2

示例 2:

示例 2

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

數據范圍

  • 1 ≤ nums.length ≤ 10 4 \texttt{1} \le \texttt{nums.length} \le \texttt{10}^\texttt{4} 1nums.length104
  • -10 4 ≤ nums[i] ≤ 10 4 \texttt{-10}^\texttt{4} \le \texttt{nums[i]} \le \texttt{10}^\texttt{4} -104nums[i]104
  • nums \texttt{nums} nums嚴格遞增順序排列

解法

思路和算法

由于二叉搜索樹的中序遍歷序列是單調遞增的,因此給定的升序數組即為二叉搜索樹的中序遍歷序列。在只有中序遍歷序列的情況下,無法唯一地確定二叉搜索樹。

為了得到高度平衡二叉搜索樹,構造的二叉搜索樹應滿足根結點的左子樹和右子樹的結點數盡可能接近。當結點總數是奇數時,根結點值應為中序遍歷序列的中間位置的結點值,根結點的左子樹和右子樹的結點數應相等;當結點總數是偶數時,根結點值應為中序遍歷序列的中間位置的兩個結點值之一,根結點的左子樹和右子樹的結點數之差的絕對值應等于 1 1 1

確定高度平衡二叉搜索樹的根結點之后,其余的結點值分別位于根結點的左子樹和右子樹中,數組中位于根結點左側的值都在左子樹中,數組中位于根結點右側的值都在右子樹中,左子樹和右子樹也是高度平衡二叉搜索樹。可以通過數學歸納法證明,如果兩個高度平衡二叉搜索樹的結點數之差的絕對值不超過 1 1 1,則這兩個高度平衡二叉搜索樹的高度之差的絕對值不超過 1 1 1

由于高度平衡二叉搜索樹的每個子樹也都是高度平衡二叉搜索樹,每個子樹包含的結點值的集合對應給定的數組中的連續子數組,因此可以使用遞歸的方式構造高度平衡二叉搜索樹,遞歸的過程中只要指定每個子樹包含的結點值的集合對應的連續子數組的下標區間 [ start , end ] [\textit{start}, \textit{end}] [start,end] 即可。

遞歸的終止條件是下標區間為空,即 start > end \textit{start} > \textit{end} start>end,此時對應的子樹為空。對于其余情況,首先根據 start \textit{start} start end \textit{end} end 計算得到根結點值的下標 mid \textit{mid} mid 并使用該結點值創建根結點,然后分別使用下標區間 [ start , mid ? 1 ] [\textit{start}, \textit{mid} - 1] [start,mid?1] [ mid + 1 , end ] [\textit{mid} + 1, \textit{end}] [mid+1,end] 創建根結點的左子樹和右子樹。

start ≤ end \textit{start} \le \textit{end} startend 時, mid \textit{mid} mid 的取值的唯一性取決于下標區間 [ start , end ] [\textit{start}, \textit{end}] [start,end] 內的元素個數的奇偶性。如果下標區間 [ start , end ] [\textit{start}, \textit{end}] [start,end] 內的元素個數是奇數,則 mid \textit{mid} mid 的取值是唯一的;如果下標區間 [ start , end ] [\textit{start}, \textit{end}] [start,end] 內的元素個數是偶數,則 mid \textit{mid} mid 的取值是不唯一的,可以是中間位置左邊的下標或者中間位置右邊的下標。

  • mid = ? start + end 2 ? \textit{mid} = \Big\lfloor \dfrac{\textit{start} + \textit{end}}{2} \Big\rfloor mid=?2start+end?? 時, mid \textit{mid} mid 是中間位置左邊的下標。

  • mid = ? start + end + 1 2 ? \textit{mid} = \Big\lfloor \dfrac{\textit{start} + \textit{end} + 1}{2} \Big\rfloor mid=?2start+end+1?? 時, mid \textit{mid} mid 是中間位置右邊的下標。

如果下標區間 [ start , end ] [\textit{start}, \textit{end}] [start,end] 內的元素個數是奇數,則上述兩種方法計算得到的 mid \textit{mid} mid 的值相同。

由此可以得到三種構造高度平衡二叉搜索樹的方法。

  • 每次都將根結點值取為中間位置左邊的下標處的值。

  • 每次都將根結點值取為中間位置右邊的下標處的值。

  • 每次隨機將根結點值取為中間位置左邊或右邊的下標處的值。

證明

為了證明上述構造高度平衡二叉搜索樹的方法的正確性,需要證明:如果兩個高度平衡二叉搜索樹的結點數之差的絕對值不超過 1 1 1,則這兩個高度平衡二叉搜索樹的高度之差的絕對值不超過 1 1 1

h ( n ) h(n) h(n) 表示有 n n n 個結點的高度平衡二叉搜索樹的高度,其中 n ≥ 1 n \ge 1 n1,規定 h ( 1 ) = 0 h(1) = 0 h(1)=0 h ( 2 ) = h ( 3 ) = 1 h(2) = h(3) = 1 h(2)=h(3)=1,則對于 1 ≤ n ≤ 3 1 \le n \le 3 1n3 h ( n ) = ? log ? n ? h(n) = \lfloor \log n \rfloor h(n)=?logn?

n ≥ 4 n \ge 4 n4 時,假設對于任意 1 ≤ m < n 1 \le m < n 1m<n 都有 h ( m ) = ? log ? m ? h(m) = \lfloor \log m \rfloor h(m)=?logm?,需要證明 h ( n ) = ? log ? n ? h(n) = \lfloor \log n \rfloor h(n)=?logn?

  • n n n 是奇數時,令 n = 2 k + 1 n = 2k + 1 n=2k+1,其中 k ≥ 1 k \ge 1 k1,則根結點的左子樹和右子樹各有 k k k 個結點。由于 k < n k < n k<n,因此 h ( k ) = ? log ? k ? h(k) = \lfloor \log k \rfloor h(k)=?logk? 已知,此時 h ( n ) = h ( k ) + 1 = ? log ? k ? + 1 h(n) = h(k) + 1 = \lfloor \log k \rfloor + 1 h(n)=h(k)+1=?logk?+1。由于 n = 2 k + 1 n = 2k + 1 n=2k+1,因此 n ? 1 = 2 k n - 1 = 2k n?1=2k log ? ( n ? 1 ) = log ? 2 k = log ? k + 1 \log (n - 1) = \log 2k = \log k + 1 log(n?1)=log2k=logk+1,取整得 ? log ? ( n ? 1 ) ? = ? log ? k ? + 1 \lfloor \log (n - 1) \rfloor = \lfloor \log k \rfloor + 1 ?log(n?1)?=?logk?+1。由于 n n n 是奇數,因此 ? log ? n ? = ? log ? ( n ? 1 ) ? \lfloor \log n \rfloor = \lfloor \log (n - 1) \rfloor ?logn?=?log(n?1)? ? log ? n ? = ? log ? k ? + 1 \lfloor \log n \rfloor = \lfloor \log k \rfloor + 1 ?logn?=?logk?+1 h ( n ) = ? log ? n ? h(n) = \lfloor \log n \rfloor h(n)=?logn?

  • n n n 是偶數時,令 n = 2 k + 2 n = 2k + 2 n=2k+2,其中 k ≥ 1 k \ge 1 k1,則根結點的左子樹和右子樹分別有 k k k 個結點和 k + 1 k + 1 k+1 個結點。由于 k + 1 < n k + 1 < n k+1<n,因此 h ( k + 1 ) = ? log ? ( k + 1 ) ? h(k + 1) = \lfloor \log (k + 1) \rfloor h(k+1)=?log(k+1)? 已知,此時 h ( n ) = h ( k + 1 ) + 1 = ? log ? ( k + 1 ) ? + 1 h(n) = h(k + 1) + 1 = \lfloor \log (k + 1) \rfloor + 1 h(n)=h(k+1)+1=?log(k+1)?+1。由于 n = 2 k + 2 = 2 ( k + 1 ) n = 2k + 2 = 2(k + 1) n=2k+2=2(k+1),因此 log ? n = log ? 2 ( k + 1 ) = log ? ( k + 1 ) + 1 \log n = \log 2(k + 1) = \log (k + 1) + 1 logn=log2(k+1)=log(k+1)+1,取整得 ? log ? n ? = ? log ? ( k + 1 ) ? + 1 \lfloor \log n \rfloor = \lfloor \log (k + 1) \rfloor + 1 ?logn?=?log(k+1)?+1 h ( n ) = ? log ? n ? h(n) = \lfloor \log n \rfloor h(n)=?logn?

因此對于任意正整數 n n n,都有 h ( n ) = ? log ? n ? h(n) = \lfloor \log n \rfloor h(n)=?logn?。由于任意兩個相鄰正整數的對數之差一定不超過 1 1 1,因此當 n ≥ 2 n \ge 2 n2 時,一定有 h ( n ) ? h ( n ? 1 ) ≤ 1 h(n) - h(n - 1) \le 1 h(n)?h(n?1)1

代碼

下面的代碼為每次都將根結點值取為中間位置左邊的下標處的值的做法。

class Solution {public TreeNode sortedArrayToBST(int[] nums) {return createBST(nums, 0, nums.length - 1);}public TreeNode createBST(int[] nums, int start, int end) {if (start > end) {return null;}int mid = (end - start) / 2 + start;return new TreeNode(nums[mid], createBST(nums, start, mid - 1), createBST(nums, mid + 1, end));}
}

下面的代碼為每次都將根結點值取為中間位置右邊的下標處的值的做法。

class Solution {public TreeNode sortedArrayToBST(int[] nums) {return createBST(nums, 0, nums.length - 1);}public TreeNode createBST(int[] nums, int start, int end) {if (start > end) {return null;}int mid = (end - start + 1) / 2 + start;return new TreeNode(nums[mid], createBST(nums, start, mid - 1), createBST(nums, mid + 1, end));}
}

下面的代碼為每次隨機將根結點值取為中間位置左邊或右邊的下標處的值的做法。

class Solution {public TreeNode sortedArrayToBST(int[] nums) {return createBST(nums, 0, nums.length - 1);}public TreeNode createBST(int[] nums, int start, int end) {if (start > end) {return null;}int mid = (end - start + (int) (Math.random() * 2)) / 2 + start;return new TreeNode(nums[mid], createBST(nums, start, mid - 1), createBST(nums, mid + 1, end));}
}

復雜度分析

  • 時間復雜度: O ( n ) O(n) O(n),其中 n n n 是數組 nums \textit{nums} nums 的長度。每個元素都被訪問一次。

  • 空間復雜度: O ( log ? n ) O(\log n) O(logn),其中 n n n 是數組 nums \textit{nums} nums 的長度。空間復雜度主要是遞歸調用的棧空間,由于構造的是高度平衡二叉搜索樹,因此遞歸調用棧的深度是 O ( log ? n ) O(\log n) O(logn)。注意返回值不計入空間復雜度。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719336.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719336.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719336.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一、低代碼平臺-數據庫設計規范

數據庫設計規范目的 a、規格化管理各個業務數據表 b、通過字段名稱快速了解表與表之間的關聯關系 c、通過字段第一位快速了解字段數據類型等等所有規范都為了更好的開發與后期系統運維。 1、數據庫設計規范 答&#xff1a;數據庫安裝必須選擇大小寫敏感&#xff1b;編碼格式…

15 easy 141. 環形鏈表

法1&#xff1a;快慢指針法&#xff1a; //給你一個鏈表的頭節點 head &#xff0c;判斷鏈表中是否有環。 // // 如果鏈表中有某個節點&#xff0c;可以通過連續跟蹤 next 指針再次到達&#xff0c;則鏈表中存在環。 為了表示給定鏈表中的環&#xff0c;評測系統內部使用整數…

Python爬蟲副業真的可行嗎?

首先回答你&#xff0c;是可行的&#xff0c;python爬蟲能當副業&#xff0c;副業的方式比較多&#xff0c;等下我會講幾種。 那學到哪個層次可以接單呢&#xff1f;主要看你是接什么樣的單&#xff0c;爬一些資料&#xff0c;視頻這種簡單的學一兩個月就沒什么問題&#xff0…

第一天 走進Docker的世界

第一天 走進Docker的世界 介紹docker的前世今生&#xff0c;了解docker的實現原理&#xff0c;以Django項目為例&#xff0c;帶大家如何編寫最佳的Dockerfile構建鏡像。通過本章的學習&#xff0c;大家會知道docker的概念及基本操作&#xff0c;并學會構建自己的業務鏡像&…

一文讀懂Persistence One- 如何將Restaking帶入Cosmos

Persistence One正在將Restaking引入Cosmos。用戶將能夠通過pSTAKE、Stride、Quicksilver和Milkyway將Liquid Staked Tokens&#xff08;如ATOM、TIA、DYDX等&#xff09;存入Persistence One&#xff0c;對其進行Restaking&#xff0c;從而安全地連接更多區塊鏈&#xff0c;首…

MySQL:數據庫中有哪些鎖

1、全局鎖 加上全局鎖后整個數據庫就處于只讀狀態了&#xff0c;這時其他線程執行以下操作&#xff0c;都會被阻塞&#xff1a; 對數據的增刪改操作&#xff0c;比如 insert、delete、update等語句&#xff1b;對表結構的更改操作&#xff0c;比如 alter table、drop table 等…

Android APK包反編譯為java文件教程

方法 流程&#xff1a; test.apk -> smali文件 -> dex文件 -> jar文件 ->java 文件 將APK包解壓為 smail文件 下載 apktool工具 apktool.jar 將 test.apk 和 apktool.jar放同一目錄下&#xff0c;并執行以下命令 java -jar apktool.jar d -f xxx.apk -o xxx(解…

【如何像網吧一樣弄個游戲菜單在家里】

GGmenu 個人家庭版游戲、應用管理 桌面圖標管理器

[環境配置]ssh連接報錯“kex_exchange_identification: read: Connection reset by peer”

已經被VScode ssh毒死好幾次了&#xff0c;都是執行命令意外中斷&#xff0c;然后又VSCode里連不上、本機Terminal也連不上了。。。 重啟遠程服務器&#xff0c;VSCode可以連上了&#xff0c; 系統ssh還是不行&#xff0c;報錯“kex_exchange_identification: read: Connecti…

容器(JAVA基礎)

一.泛型 在Java中,泛型(Generics)是JDK 5.0引入的一個新特性,它允許在定義類、接口和方法時使用類型參數(type parameters)。類型參數在使用前必須先被實際類型(如Integer、String等)替代,這個過程稱作類型實例化或類型擦除。泛型提供了編譯時類型安全,減少了運行時…

CSS~~

CSS是一門語言&#xff0c;用于控制網頁表現 CSS(Cascading Style Sheet):層疊樣式表 W3C標準:網頁主要由三部分組成 結構:HTML 表現: CSS 行為:JavaScript 1&#xff0c;CSS的導入方式 &#xff08;1&#xff09;內聯樣式 在標簽內部使用style屬性&#xff0c;屬性值是cs…

類 Unix 系統的文件目錄結構

以下是類 Unix 系統的文件目錄結構、各個目錄主要存放的文件以及縮寫的全稱的詳細說明&#xff1a; 根目錄 /&#xff1a; 全稱: Root Directory說明&#xff1a;根目錄是整個文件系統的起點&#xff0c;包含了所有其他目錄和文件。 /bin 目錄&#xff1a; 全稱: Binary說明&a…

Nginx最常用的指令

服務管理 sudo systemctl status nginx # nginx當前狀態 sudo systemctl reload nginx # 重新加載 nginx sudo systemctl restart nginx # 重啟nginxsudo nginx -t # 檢查語法 nginx # 啟動 nginx -s reload # 重啟 nginx -s stop # 關閉進程 nginx -s quit #…

Java學習筆記002——類的修飾符

在Java語言中&#xff0c;類的訪問修飾符決定了其它類能夠訪問該類的方式。類有如下4種訪問修飾符&#xff0c;在創建類時用于類的聲明&#xff1a; 1、public: 當一個類被聲明為public時&#xff0c;它可以從任何其他類中被訪問&#xff0c;無論這些類位于哪個包中。通常&am…

uniapp使用vue3語法構建自定義導航欄,適配小程序膠囊

具體代碼 <template><view class"nav-wrapper-container" :style"height:navBarHeight px"><view class"nav-status-container" :style"height:navstatusBarHeight px;" /><view v-if"isCustom" clas…

數字化轉型導師堅鵬:BLM證券公司數字化轉型戰略

BLM證券公司數字化轉型戰略 ——以BLM模型為核心&#xff0c;實現知行果合一 課程背景&#xff1a; 很多證券公司存在以下問題&#xff1a; 不知道如何系統地制定證券公司數字化轉型戰略&#xff1f; 不清楚其它證券公司數字化轉型戰略是如何制定的&#xff1f; 不知道…

Redis 淘汰策略、持久化、高可用

淘汰策略 只有 redis 內存空間已滿并且往里面寫新數據&#xff0c;才會觸發淘汰策略。通過 expire / / /pexpire 讓 key-value 過期&#xff0c;從而讓 redis 清除這個 key-value。value 的數據結構typedef struct redisObject {unsigned tpye:4;unsigned encoding:4;// 判斷哪…

個人數倉開發面試題記錄

一.廣州電商公司 1.簡單自我介紹 2.介紹下之前的公司離線數倉項目 3.mysql和hive區別&#xff1f; 4.sql的執行順序&#xff1f; 5.hive的優化 6.說下你之前公司來&#xff0c;你的技能層次在每個公司&#xff1f;你怎么評價你的技能&#xff1f; 7.你的之前業務主要是做什么&…

Linux基礎命令[10]-cmp

文章目錄 1. cmp 命令說明2. cmp 命令語法3. cmp 命令示例3.1 不加參數3.2 -b&#xff08;顯示不同的字節&#xff09;3.3 -i&#xff08;跳過字節&#xff09;3.4 -l&#xff08;顯示所有不同&#xff09;3.5 -n&#xff08;比較n個字節&#xff09;3.6 -s&#xff08;不顯示信…

el-select 不能重復選擇

el-select 不能重復選擇&#xff0c;注意&#xff1a;刪除后可以再次重新被選擇 <el-form-item><el-select v-model"attribute.attributeSelect" change"changeSelect()" placeholder"請選擇屬性分組" clearable><el-optionv-fo…