LeetCode: Convert Sorted List to Binary Search Tree 解題報告

Convert Sorted List to Binary Search Tree 

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.html

 

Show Tags

SOLUTION 1:

這個方法比較暴力,每次遍歷當前list,找到中間的節點,創建 root,分別使用遞歸創建左樹以及右樹,並將左右樹掛在root之下。但這個算法會複雜度很高。
創建root次數爲N,每次遍歷最多N次,最壞爲N平方(實際不會這麼多)
 1 public TreeNode sortedListToBST1(ListNode head) {
 2         ListNode fast = head;
 3         ListNode slow = head;
 4         
 5         ListNode pre = head;
 6         
 7         if (head == null) {
 8             return null;
 9         }
10         
11         TreeNode root = null;
12         if (head.next == null) {
13             root = new TreeNode(head.val);
14             root.left = null;
15             root.right = null;
16             return root;
17         }
18         
19         // get the middle node.
20         while (fast != null && fast.next != null) {
21             fast = fast.next.next;
22             
23             // record the node before the SLOW.
24             pre = slow;
25             slow = slow.next;
26         }
27         
28         // cut the list to two parts.
29         pre.next = null;
30         TreeNode left = sortedListToBST1(head);
31         TreeNode right = sortedListToBST1(slow.next);
32         
33         root = new TreeNode(slow.val);
34         root.left = left;
35         root.right = right;
36         
37         return root;
38     }
View Code

 

SOLUTION 2:

 這個解法使用一個參數來記錄當前正在操做的List Node. DFS自己的效果是,從head直到尾部建樹,而且將currNode移動到size+1處。
這樣能夠在1次iterator 咱們的List後直接創建樹。
這是一種Bottom-up的建樹方法。若是咱們使用C++,則能夠將List Node的指針直接作爲入參。咱們這裏使用了相似的方法,不過,
Java不能使用指針,因此咱們自建一個自定義的類,裏面只有一個ListNode,這樣咱們就能方便地修改入參了(好糾結啊,這時主頁君就開始懷念起C的指針了),
:)
C++版本能夠參見張磊哥哥的解答喔:)
 1 public TreeNode sortedListToBST(ListNode head) {
 2         if (head == null) {
 3             return null;
 4         }
 5         
 6         int size = 0;
 7         ListNode cur = head;
 8         while (cur != null) {
 9             size++;
10             cur = cur.next;
11         }
12          
13         CurrNode curNode = new CurrNode(head); 
14         return sortedListToBSTHelp(curNode, size);
15     }
16     
17     public class CurrNode {
18         ListNode node;
19         
20         CurrNode(ListNode node) {
21             this.node = node;
22         }
23     }
24     
25     // when the recursion is done, the curr node should point to the node
26     // which is the next of the block.
27     public TreeNode sortedListToBSTHelp(CurrNode curr, int size) {
28         if (size <= 0) {
29             return null;
30         }
31         
32         TreeNode left = sortedListToBSTHelp(curr, size/2);
33         
34         // because we want to deal with the right block.
35         TreeNode root = new TreeNode(curr.node.val);
36         curr.node = curr.node.next;
37         
38         TreeNode right = sortedListToBSTHelp(curr, size - 1 - size/2);
39         
40         root.left = left;
41         root.right = right;
42         
43         return root;
44     }
View Code

 

SOLUTION 3:

這個解法使用一個instance variable 來記錄當前正在操做的List Node. DFS自己的效果是,從head直到尾部建樹,而且將currNode移動到size+1處。
這樣能夠在1次iterator 咱們的List後直接創建樹。
這是一種Bottom-up的建樹方法。若是咱們使用C++,則能夠將List Node直接作爲入參來改變之而不須要使用實例變量。
問題是:咱們若是能夠的話,儘可能不要使用實例變量,由於它是各個Method 共享的,因此這個方法存在風險。由於變量有可能被別的方法修改。
 
這個dfs的意思就是 對一個以head 起始的list, size爲大小的list建一個樹,一個bfs樹
而且這個dfs有一個做用 會把指針移動到這個要建的樹的下一個位置
 
這樣 咱們先創建左樹,        TreeNode left = dfs(head, size / 2);
通過這一行 cur就移動到了中間
咱們創建 一個根         TreeNode root = new TreeNode(curNode.val);

把cur移動到下一個     curNode = curNode.next;
再用遞歸創建右樹      
 
構造咱們想要的樹 返回根結果
root.left = left;
root.right = right;
return root;
 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; next = null; }
 7  * }
 8  */
 9 /**
10  * Definition for binary tree
11  * public class TreeNode {
12  *     int val;
13  *     TreeNode left;
14  *     TreeNode right;
15  *     TreeNode(int x) { val = x; }
16  * }
17  */
18 public class Solution {
19     ListNode curNode = null;
20     
21     public TreeNode sortedListToBST(ListNode head) {
22         if (head == null) {
23             return null;
24         }
25         
26         int size = 0;
27         ListNode cur = head;
28         while (cur != null) {
29             size++;
30             cur = cur.next;
31         }
32         
33         curNode = head;
34         return dfs(head, size);
35     }
36     
37     // Use the size to control.
38     public TreeNode dfs(ListNode head, int size) {
39         if (size <= 0) {
40             return null;
41         }
42         
43         TreeNode left = dfs(head, size / 2);
44         TreeNode root = new TreeNode(curNode.val);
45         
46         // move the current node to the next place.
47         curNode = curNode.next;
48         TreeNode right = dfs(curNode, size - size / 2 - 1);
49         
50         root.left = left;
51         root.right = right;
52         
53         return root;
54     }
55 }
View Code
相關文章
相關標籤/搜索