• 有序数组、链表转换为平衡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;
    }
    
  • 相关阅读:
    codeforces 765 F Souvenirs 线段树+set
    codeforces 768 E 变形NIM博弈/手写sg函数
    BZOJ 1001 狼抓兔子(网络流)
    BZOJ 2957 楼房重建 (分块)
    CodeForces
    CodeForces
    HYSBZ
    SPOJ
    Codeforces-963 D Frequency of String
    中石油2019寒假集训第一场(新生场)(补题)
  • 原文地址:https://www.cnblogs.com/yxym2016/p/14547487.html
Copyright © 2020-2023  润新知