LeetCode – Convert Sorted List to Binary Search Tree (Java)

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

Thoughts

If you are given an array, the problem is quite straightforward. But things get a little more complicated when you have a singly linked list instead of an array. Now you no longer have random access to an element in O(1) time. Therefore, you need to create nodes bottom-up, and assign them to its parents. The bottom-up approach enables us to access the list in its order at the same time as creating nodes.

Java Solution

//  Definition for singly-linked list.
class ListNode {
	int val;
	ListNode next;
 
	ListNode(int x) {
		val = x;
		next = null;
	}
}
 
// Definition for binary tree
class TreeNode {
	int val;
	TreeNode left;
	TreeNode right;
 
	TreeNode(int x) {
		val = x;
	}
}
 
public class Solution {
	static ListNode h;
 
	public TreeNode sortedListToBST(ListNode head) {
		if (head == null)
			return null;
 
		h = head;
		int len = getLength(head);
		return sortedListToBST(0, len - 1);
	}
 
	// get list length
	public int getLength(ListNode head) {
		int len = 0;
		ListNode p = head;
 
		while (p != null) {
			len++;
			p = p.next;
		}
		return len;
	}
 
	// build tree bottom-up
	public TreeNode sortedListToBST(int start, int end) {
		if (start > end)
			return null;
 
		// mid
		int mid = (start + end) / 2;
 
		TreeNode left = sortedListToBST(start, mid - 1);
		TreeNode root = new TreeNode(h.val);
		h = h.next;
		TreeNode right = sortedListToBST(mid + 1, end);
 
		root.left = left;
		root.right = right;
 
		return root;
	}
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • Cullan Ln

    public class Solution {
    public TreeNode sortedListToBST(ListNode head) {
    if (head == null) {
    return null;
    }
    ListNode end = head;
    while (end.next != null) {
    end = end.next;
    }
    return sortedListToBST(head, end);
    }
    public TreeNode sortedListToBST(ListNode head, ListNode end) {
    if (end.next == head) { //basically same ideas as start > end; occurs when one node left so head > midPrev and mid.next > end
    return null;
    }
    ListNode midPrev = findMidPrev(head, end);
    ListNode mid = midPrev.next;
    TreeNode node = new TreeNode(mid.val);
    node.left = sortedListToBST(head, midPrev);
    node.right = sortedListToBST(mid.next, end);

    return node;
    }
    //return node previous to mid
    public ListNode findMidPrev(ListNode head, ListNode end) {
    ListNode slowPrev = new ListNode(0);
    slowPrev.next = head;
    ListNode slow = head;
    ListNode fast = head;

    while (fast.next != end && fast != end && fast.next != null && fast != null) {
    slowPrev = slowPrev.next;
    slow = slow.next;
    fast = fast.next.next;
    }

    return slowPrev;
    }
    }

  • kamal al-din

    For mid, your calculation would be better protected against overflow if it was this: int mid = start + (end-start)/2 ..Funny story, this was actually a bug in BST’s for a long time until someone found that it caused overflow. Hope this helps!
    Elegant solution otherwise!

  • jason zhang
  • Chong

    Hi. Can we put the input list as a member of first sortedListToBST function, and then pass it to second sortedListToBST function each time when calling it? If wo do it like this, and we move the pointer inside of sortedListToBST function, will this movement aware by caller? Thank you!

  • CopperCash

    def build_from_sorted_list(cls, start_node, end_node=None):
    if None == start_node:
    return None
    elif start_node is end_node:
    return cls(start_node.value)

    slow, fast = start_node, start_node
    while (end_node is not slow.next) and (end_node is not fast.next) and (end_node is not fast.next.next):
    slow = slow.next
    fast = fast.next.next

    node = cls(slow.value)
    node.left = cls.build_from_sorted_list(start_node, slow)
    node.right = cls.build_from_sorted_list(slow.next, end_node)

    return node

    recursive python version

  • Amir

    elegant code, well done!

  • Sidharth

    static keyword is not needed ….using only class variable shall work

  • Abhishek

    yes but the whole point of implementing it differently from arrays is list does not permit random access and we are accessing actual node data sequentially in this program!!

  • KrishnaK

    Can we do the same without the static ListNode h
    Can we pass it as a parameter to the method sortedListtoBST?

  • ryanlr

    Yes, good idea!

  • Vijay

    Hi, can we not build a AVL/RB tree and balance them on the go?

  • ZG Yao

    Hi.
    Do we need to use ceiling function to get the middle value?
    If the list is 1 -> 2 -> 3 -> 4 -> 5 -> 6, then the solution you provide would first get 3 not 4. (Using 4 as root would generate a good-looking tree).