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.

 

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

 

你可能感兴趣的:(Binary search)