LeetCode刷题笔录Covert Sorted List to Binary Search Tree

30 篇文章 0 订阅
15 篇文章 0 订阅

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

思路并不难。每次选链表的中间元素作为当前节点,左子树递归左半边链表,右子树递归右半边链表。如果这不是链表而是数组的话那么很简单了。但是这是链表,没有random access,因此需要写两个helper function来寻找中间元素以及中间元素之前的元素。

这里有很多地方容易出错,比如寻找mid的时候head, tail不能是null,head.val不能大于tail.val等。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; next = null; }
 * }
 */
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        if(head == null)
            return null;
        ListNode tail = head;
        while(tail.next != null)
            tail = tail.next;
        TreeNode root = recursive(head, head, tail);
        return root;
    }
    
    public TreeNode recursive(ListNode head, ListNode start, ListNode end){
        ListNode mid = findMid(start, end);
        if(mid == null)
            return null;
        TreeNode newNode = new TreeNode(mid.val);
        newNode.left = recursive(head, start, findPrevious(start, mid));
        newNode.right = recursive(head, mid.next, end);
        return newNode;
    }
    
    public ListNode findPrevious(ListNode head, ListNode node){
        ListNode p = head;
        if(p == null || p.val >= node.val)
            return null;
        while(p.next != node)
            p = p.next;
        return p;
    }
    public ListNode findMid(ListNode head, ListNode tail){
        if(head == null || tail == null || head.val > tail.val)
            return null;
        if(head == tail)
            return head;
        ListNode slow = head;
        ListNode fast = head;
        while(fast.val != tail.val && fast.next.val != tail.val){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
}

更新:

上面的方法有点复杂了,毕竟list找中间元素不是很容易。其实可以这样想:一个BST的in order traversal就是一个有序的list,那么其实只要按照这个list来做一个in order traversal就可以了。有点拧,其实就是中序遍历。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; next = null; }
 * }
 */
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode sortedListToBST(ListNode head) {
        if(head == null)
            return null;
        
        //get the length of the list
        int count = 0;
        ListNode node = head;
        while(node != null){
            node = node.next;
            count++;
        }
        ArrayList<ListNode> list = new ArrayList<ListNode>();
        list.add(head);
        return recur(list, 0, count - 1);
    }
    
    public TreeNode recur(ArrayList<ListNode> list, int start, int end){
        if(start > end)
            return null;
        int mid = (start + end) / 2;
        
        TreeNode left = recur(list, start, mid - 1);
        //get the root node from the in order traversal
        TreeNode root = new TreeNode(list.get(0).val);
        root.left = left;
        list.set(0, list.get(0).next);
        root.right = recur(list, mid + 1, end);
        
        return root;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值