1. 程式人生 > 實用技巧 >leetcode 精選top面試題 - 108. 將有序陣列轉換為二叉搜尋樹

leetcode 精選top面試題 - 108. 將有序陣列轉換為二叉搜尋樹

108. 將有序陣列轉換為二叉搜尋樹

將一個按照升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。

本題中,一個高度平衡二叉樹是指一個二叉樹每個節點的左右兩個子樹的高度差的絕對值不超過 1。

示例:

思路參考:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/solution/jiang-you-xu-shu-zu-zhuan-huan-wei-er-cha-sou-s-33/

思路一:中序遍歷,總是選擇中間位置左邊的數字作為根節點

陣列中間位置左邊元素為根, 遞迴將左邊元素建為左子樹,遞迴將右邊元素建為右子樹

int mid = left + (right - left) / 2;  // 向下取整,取得的是中間位置左邊的元素

 1 class Solution {
 2 
 3     // 陣列中間左邊的元素為根, 左邊元素為左子樹,右邊元素為右子樹
 4     public TreeNode buildTree(int[] nums, int left, int right){
 5         if(left > right){
 6             return null;
 7         }
 8         int mid = left + (right - left) / 2;  // 向下取整,取得的是中間位置左邊的元素
 9         TreeNode root = new
TreeNode(nums[mid]); 10 root.left = buildTree(nums, left, mid - 1); 11 root.right = buildTree(nums, mid + 1, right); 12 return root; 13 } 14 15 public TreeNode sortedArrayToBST(int[] nums) { 16 return buildTree(nums, 0, nums.length - 1); 17 } 18 }
leetcode 執行用時:0 ms, 在所有Java提交中擊敗了100.00%的使用者 記憶體消耗:38.3 MB, 在所有Java提交中擊敗了86.66%的使用者

複雜度分析:

時間複雜度:O(n)。遍歷了整個陣列,所以時間複雜度為O(n)。

空間複雜度:O(logn)。取決於遞迴棧的深度,因為建成的樹是一棵平衡二叉樹,所以樹的深度為O(logn), 所以空間複雜度為O(logn)。

思路二:中序遍歷,總是選擇中間位置的數字作為根節點

思路和思路一一樣,只不過這次總是選擇中間位置的數字作為根節點,因為建出的平衡二叉樹可能有多種形態。

int mid = left + (right - left + 1) / 2;  // 向下取整,取得的是中間位置的元素

 1 class Solution {
 2 
 3     // 陣列中間元素為根, 左邊元素為左子樹,右邊元素為右子樹
 4     public TreeNode buildTree(int[] nums, int left, int right){
 5         if(left > right){
 6             return null;
 7         }
 8         int mid = left + (right - left + 1) / 2;
 9         TreeNode root = new TreeNode(nums[mid]);
10         root.left = buildTree(nums, left, mid - 1);
11         root.right = buildTree(nums, mid + 1, right);
12         return root;
13     }
14 
15     public TreeNode sortedArrayToBST(int[] nums) {
16         return buildTree(nums, 0, nums.length - 1);
17     }
18 }
leetcode 執行用時:0 ms, 在所有Java提交中擊敗了100.00%的使用者 記憶體消耗:38.3 MB, 在所有Java提交中擊敗了86.66%的使用者

複雜度分析:

時間複雜度:O(n)。遍歷了整個陣列,所以時間複雜度為O(n)。

空間複雜度:O(logn)。取決於遞迴棧的深度,因為建成的樹是一棵平衡二叉樹,所以樹的深度為O(logn), 所以空間複雜度為O(logn)。

思路三:中序遍歷,選擇任意一箇中間位置數字作為根節點

思路和思路一一樣,只不過這次總是選擇中間位置的數字作為根節點,因為建出的平衡二叉樹可能有多種形態。

mid = left + (right - left) / 2; 或者 mid = left + (right - left+ 1) / 2

 1 class Solution {
 2 
 3     // 陣列中間元素為根, 左邊元素為左子樹,右邊元素為右子樹
 4     public TreeNode buildTree(int[] nums, int left, int right){
 5         if(left > right){
 6             return null;
 7         }
 8         int mid = left + (right - left + new Random().nextInt(2)) / 2;
 9         TreeNode root = new TreeNode(nums[mid]);
10         root.left = buildTree(nums, left, mid - 1);
11         root.right = buildTree(nums, mid + 1, right);
12         return root;
13     }
14 
15     public TreeNode sortedArrayToBST(int[] nums) {
16         return buildTree(nums, 0, nums.length - 1);
17     }
18 }
執行用時:2 ms, 在所有Java提交中擊敗了6.30%的使用者, 這裡主要是建立 Random物件產生了開銷 記憶體消耗:38 MB, 在所有Java提交中擊敗了95.33%的使用者

複雜度分析:

時間複雜度:O(n)。遍歷了整個陣列,所以時間複雜度為O(n)。

空間複雜度:O(logn)。取決於遞迴棧的深度,因為建成的樹是一棵平衡二叉樹,所以樹的深度為O(logn), 所以空間複雜度為O(logn)。