109. Convert Sorted List to Binary Search Tree
Solution1: use 108, convert to list then do the same.
T: O(2n)
class Solution {
public TreeNode sortedListToBST(ListNode head) {
List<Integer> list = new ArrayList<>();
ListNode temp = head;
while (temp != null) {
list.add(temp.val);
temp = temp.next;
}
return dfs(list, 0, list.size()-1);
}
private TreeNode dfs(List<Integer> list, int left, int right) {
if (left > right) {
return null;
}
int mid = (left + right)/2;
TreeNode root = new TreeNode(list.get(mid));
root.left = dfs(list, left, mid-1);
root.right = dfs(list, mid + 1, right);
return root;
}
}
solution 2: use slow fast pointer to find mid
and dfs(head, null) to build BS tree
slower than solution1, because needs to find mid every time...
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode sortedListToBST(ListNode head) {
return dfs(head, null);
}
private TreeNode dfs(ListNode begin, ListNode end) {
if (begin == end) {
return null;
}
ListNode mid = findMid(begin, end); // (5, 9), mid = 5
TreeNode root = new TreeNode(mid.val); // 5
root.left = dfs(begin, mid); // 5,5 -> means it finished
root.right = dfs(mid.next, end);
return root;
}
private ListNode findMid(ListNode begin, ListNode end) { // exclude end
ListNode fast = begin;
ListNode slow = begin;
while (fast != end && fast.next != end) {
fast = fast.next.next; // 9
slow = slow.next; // 0
}
return slow;
}
}
/***
-10 -3 1 0 5 6 9
0
/. \
-3 6
/\. /\
-10 1 5 9
so it actually asks find max node, then do left part , right part DFS
*/
Solution3: directly uses inorder
T: O(n)
class Solution {
private ListNode cur;
public TreeNode sortedListToBST(ListNode head) {
int len = 0;
ListNode temp = head;
while (temp != null) {
len++;
temp = temp.next;
}
this.cur = head;
return dfs(0, len-1); // still needs len, to control the base case
}
private TreeNode dfs(int left, int right) {
if (left > right) {
return null;
}
int mid = (left + right)/2;
TreeNode leftTreeNode = dfs(left, mid-1);
TreeNode root = new TreeNode(cur.val);
cur = cur.next;
TreeNode rightTreeNode = dfs(mid+1, right);
root.left = leftTreeNode;
root.right = rightTreeNode;
return root;
}
}
improved Solution 3
use a class Wrapper to avoid using global variable:
class Solution {
class ListNodeWrapper {
private ListNode node;
ListNodeWrapper(ListNode node) {
this.node = node;
}
}
public TreeNode sortedListToBST(ListNode head) {
int len = 0;
ListNode temp = head;
while (temp != null) {
len++;
temp = temp.next;
}
return dfs(new ListNodeWrapper(head), 0, len-1); // still needs len, to control the base case
}
private TreeNode dfs(ListNodeWrapper cur, int left, int right) {
if (left > right) {
return null;
}
int mid = (left + right)/2;
TreeNode leftTreeNode = dfs(cur, left, mid-1);
TreeNode root = new TreeNode(cur.node.val);
cur.node = cur.node.next;
TreeNode rightTreeNode = dfs(cur, mid+1, right);
root.left = leftTreeNode;
root.right = rightTreeNode;
return root;
}
}
Last updated