Leetcode __108. 將有序陣列轉換為二叉搜尋樹
阿新 • • 發佈:2019-01-27
問題描述
將一個按照升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。
本題中,一個高度平衡二叉樹是指一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1
示例:
給定有序陣列: [-10,-3,0,5,9],
一個可能的答案是:[0,-3,9,-10,null,5],它可以表示下面這個高度平衡二叉搜尋樹:
0
/ \
-3 9
/ /
-10 5
思路
先理解幾個概念:
平衡二叉樹:是一種二叉排序樹,其中每一個節點的左子樹和右子樹的高度差至多等於1.
二叉搜尋樹:(二叉排序樹)又稱二叉查詢樹,它或者是一棵空樹,或者具有一下性質的二叉樹
- 若它的左子樹不空,則左子樹上的所有節點的值均小於它的根節點的值
- 若它的右子樹不空,則右子樹上的所有節點的值均大於它根節點的值
- 它的左右子樹也分別為二叉排序樹
當對一棵二叉搜尋數進行中序遍歷的時候,就可以得到一個有序的序列,這樣的數稱為二叉排序或搜尋樹
構造一棵二叉排序或搜尋樹的目的,並不是為了排序,而是為了提高查詢和插入刪除關鍵字的速度。
從概念中可以理解出:有序序列的中間值即為根節點,左右兩邊陣列各自成二叉搜尋樹,遞迴是最簡單的實現方式
實現
/**
1. Definition for a binary tree node.
2. public class TreeNode {
3. int val;
4. TreeNode left;
5. TreeNode right;
6. TreeNode(int x) { val = x; }
7. }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if (nums == null || nums.length == 0) {
return null;
}
return creatSub(nums, 0, nums.length-1);
}
private static TreeNode creatSub(int[] nums,int start,int end){
int len = nums.length;
if (start > end) {
return null;
}
int rootnum = (start + end) / 2;
TreeNode root = new TreeNode(nums[rootnum]);//注意是中間是陣列的值,不是排序位置
root.left = creatSub(nums, start, rootnum-1);//遞迴,要傳入變數值
root.right = creatSub(nums, rootnum + 1, end);
return root;
}
}
犯錯
- 在遞迴時候思路還停留在迴圈中,思路不清晰;
- 邊界值處理不好,第一次傳入從0開始到長度-1結束,若不-1,則越界;
- 建立根節點時候,要傳入的 是中間陣列的值,不是位置;
- 遞迴要傳入變數,不能是具體的值;
- 每次遞迴呼叫子方法的時候,要把中間值根節點的值去掉,故rootnum-1,rootnum+1
實現2(不推薦)
從思路中我們知道,每次把中間根節點拋開,左右兩邊各自陣列再遞迴呼叫函式即可,但這其中要複製陣列,佔用空間較多,比較慢,
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedArrayToBST(int[] nums){
if (nums == null || nums.length == 0) {
return null;
}
int len = nums.length;
TreeNode root = new TreeNode(nums[len / 2]);
int[] leftnum = new int[len / 2];
int[] rightnum =new int[len - len / 2 - 1];
System.arraycopy(nums,0,leftnum,0,len/2);
System.arraycopy(nums,len/2+1,rightnum,0,len - len / 2 - 1);
root.left = sortedArrayToBST(leftnum);
root.right = sortedArrayToBST(rightnum);
return root;
}
}
這裡copy陣列時候用了native方法,可以比賦值陣列快一些
小結
本問題考察的就是二分查詢,每次取中間值,再對各自邊陣列遞迴,但不一樣的是,取的中間值,是中間陣列的值,記住這點即可。