0109. Convert Sorted List to Binary Search Tree - kumaeki/LeetCode GitHub Wiki

0109. Convert Sorted List to Binary Search Tree


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

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

Example 1:

Input: head = [-10,-3,0,5,9]
Output: [0,-3,9,-10,null,5]
Explanation: One possible answer is [0,-3,9,-10,null,5], which represents the shown height balanced BST.

Example 2:

Input: head = []
Output: []

Example 3:

Input: head = [0]
Output: [0]

Example 4:

Input: head = [1,3]
Output: [3,1]

Constraints:

  • The number of nodes in head is in the range [0, 2 * 104].
  • -10^5 <= Node.val <= 10^5

解法1

二分. 因为list已经排好序了, 所以每次用快慢指针找到中间节点, 然后分为左右两边, 递归寻找中间节点分别设置为左节点和右节点.

/**
 * 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 helper(head, null);
    }
    
    private TreeNode helper(ListNode node, ListNode limit){
        // 如果node为空, 或者等于右边界, 那么返回空
        if(node == null || node == limit)
            return null;
        
        // 定义快指针和指针
        ListNode fast = node, slow = node;
        // 用快慢指针从node 开始遍历指针直到边界
        while(fast != null && fast.next != null && fast != limit && fast.next != limit){
            slow = slow.next;
            fast = fast.next.next;
        }
        
        // node的值就是当前treenode的值
        TreeNode res = new TreeNode(slow.val);
        
        // 计算左节点
        res.left = helper(node, slow);
        // 计算右节点
        res.right = helper(slow.next, limit);
        
        return res;
    }
}

解法2

如果允许对list进行更改, 那么可以在每次找到中心点时, 把list一分为2, 这样就可以不用每次保存limit

/**
 * 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 helper(head);
    }
    
    private TreeNode helper(ListNode node){
        // 如果node为空, 那么返回空
        if(node == null)
            return null;
        
        if (node.next == null) 
            return new TreeNode(node.val);
        
        // 定义快指针和指针
        ListNode fast = node, slow = node, pre = null;
        // 用快慢指针从node 开始遍历指针直到边界
        while(fast != null && fast.next != null){
            pre = slow;
            slow = slow.next;
            fast = fast.next.next;
        }
        
        // node的值就是当前treenode的值
        TreeNode res = new TreeNode(slow.val);
        // 从slow处切断list
        if(pre != null)
            pre.next = null;
        
        // 计算左节点
        res.left = helper(node);
        // 计算右节点
        res.right = helper(slow.next);

        return res;
    }
}