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.
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 }
SOLUTION 2:
这个解法使用一个参数来记录当前正在操作的List Node. DFS本身的效果是,从head直到尾部建树,并且将currNode移动到size+1处。
View Code
这样可以在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 }
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有一个作用 会把指针移动到这个要建的树的下一个位置
并且这个dfs有一个作用 会把指针移动到这个要建的树的下一个位置
这样 我们先建立左树, TreeNode left = dfs(head, size / 2);
经过这一行 cur就移动到了中间
我们建立 一个根 TreeNode root = new TreeNode(curNode.val);
把cur移动到下一个 curNode = curNode.next;
再用递归建立右树
经过这一行 cur就移动到了中间
我们建立 一个根 TreeNode root = new TreeNode(curNode.val);
把cur移动到下一个 curNode = curNode.next;
再用递归建立右树
构造我们想要的树 返回根结果
root.left = left;
root.right = right;
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 }