【LeetCode刷题记录】109.有序链表转换二叉搜索树

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

题意:

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

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

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

       0
      / \
    -3   9
    /   /
  -10  5
解题思路:

其实解题思路比较简单,就是每次找链表的中值就是根节点,然后划分链表为左右两棵子树然后继续递归求解,但是在实现的过程中能够进行一些优化,比较粗暴的实现就是用list存链表,然后每次递归的时候从list里面找中值

java实现-List转存链表查找中值

public List<Integer> list;
    public TreeNode buildTree(int left,int right){
        if(left>right) return null;
        int mid = (left+right+1) / 2;
        TreeNode cur = new TreeNode(list.get(mid));
        //System.out.println(cur.val);
        cur.left = buildTree(left,mid-1);
        cur.right = buildTree(mid+1,right);
        return cur;

    }
    public TreeNode sortedListToBST(ListNode head) {
            list = new ArrayList<Integer>(); //还是用list存吧
            while(head!=null){
                list.add(head.val);
                head = head.next;
            }
            return buildTree(0,list.size()-1);
    }

但是使用List存链表无可避免有一个O(N)的遍历操作,对此进行优化的话,可能考虑使用快慢指针查找单链表的中值,但是在查找到中值之后对左子树进行递归的时候,需要删除右子树上的节点,所以需要一个pre_mid指针,指向中值节点的上一个节点,在递归左子树之前把其next指针置为空,即pre_mid.next=null

java实现-快慢指针-前驱指针

 public ListNode midItem(ListNode head){
        if(head==null) return null;
        ListNode pre = null;
        ListNode fast = head;
        while(fast!=null&&fast.next!=null){//快慢指针的循环条件的问题
            pre = head;
            head = head.next;
            fast = fast.next.next;
        }
        return pre;
    }
   public TreeNode sortedListToBST(ListNode head) {
        //快慢指针找中点
        if(head==null) return null;
        ListNode pre_mid = midItem(head);
        ListNode mid = pre_mid==null? head:pre_mid.next;
        TreeNode cur = new TreeNode(mid.val);
        if(pre_mid!=null){
            pre_mid.next = null;
            cur.left = sortedListToBST(head);
        }
        cur.right = sortedListToBST(mid.next);
        return cur;  
    }

查看题解发现还有一种利用中序遍历二叉搜索树的特性进行递归优化实现的方式,也比较巧妙,首先对链表求长度,然后可以按照长度进行递归了,然后再中序的位置上对节点进行赋值,此时的数据变化就是链表的顺序

java实现-中序优化

 public ListNode listnode;
    public TreeNode buildTree(int left,int right){
        if(left>right) return null;
        int mid = (left+right+1) / 2;
        TreeNode cur = new TreeNode();
        //System.out.println(cur.val);
        cur.left = buildTree(left,mid-1);
        cur.val = listnode.val;//中序的位置上设置值
        listnode = listnode.next; //更新到链表的下一个值
        cur.right = buildTree(mid+1,right);
        return cur;
    }
    //和中序遍历结合起来
    public TreeNode sortedListToBST(ListNode head) {
        int len = 0;
        listnode = head;
        while(head!=null){
            len++;
            head = head.next;
        }
        return buildTree(0,len-1);
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值