有序数组、链表转换为平衡BST(力扣108、109题)

108.有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

解析

使用二分法递归创建高度平衡的BST树

public TreeNode sortedArrayToBST(int[] nums){

    if (nums == null || nums.length == 0){
        return null;
    }

    int l = 0;
    int r = nums.length - 1;
    return createTree(nums,l,r);
}


private TreeNode createTree(int[] nums,int l,int r){

    if (l > r){
        return null;
    }

    int mid = (r - l) / 2 + l;

    TreeNode root = new TreeNode(nums[mid]);

    root.left = createTree(nums,l,mid - 1);
    root.right = createTree(nums,mid + 1,r);

    return root;
}

109.有序链表转换二叉搜索树

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例

给定的有序链表: [-10, -3, 0, 5, 9],

一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:

      0
     / \
   -3   9
   /   /
 -10  5

解析

方法一:遍历有序链表,将链表中每个节点的值存入一个list中,list是一个有序集合,所以会按照存入集合以后,依旧是有序的,然后利用二分法就能创建二叉平衡搜索树。

方法二:对有序链表直接使用二分法,那么如何定位有序链表的中间节点呢?这里采用一快一慢两个指针的方式寻找链表的中间节点,慢指针一次走一步,快指针一次走两步,当快指针达到链表的链表的结尾的时候,慢指针所指的就是链表的中间节点的位置。

public TreeNode sortedListToBST(ListNode head) {

    if (head == null){
        return null;
    }

    if (head.next == null){
        return new TreeNode(head.val);
    }

    ListNode preMid = findMidNode(head);
    ListNode midNode = preMid.next;
    TreeNode root = new TreeNode(midNode.val);
    // 将中间节点之前的部分与其之后的部分断开
    preMid.next = null;
    root.left = sortedListToBST(head);
    root.right = sortedListToBST(midNode.next);

    return root;
}


private ListNode findMidNode(ListNode head){

    ListNode slow = head;
    ListNode fast = head;
	// 中间节点的前驱节点
    ListNode premid = head;
    while (fast != null && fast.next != null){

        premid = slow;
        slow = slow.next;
        fast = fast.next.next;
    }
    return premid;
}
posted @ 2021-03-17 09:35  有心有梦  阅读(69)  评论(0编辑  收藏  举报