力扣解题思路:23. 合并K个升序链表

23. 合并K个升序链表

思路:在这里插入图片描述
方法1:可以采用归并排序的思路,先两组两组分开,然后两两合并,自然而然要用到递归了。

首先定义递归出口:

    if(lists.length == 0) return null;
    if(lists.length == 1) return lists[0];
    if(lists.length == 2) return mergeTwoLists(lists[0],lists[1]);

然后将数组分为两组:

    int mid = lists.length/2;
    ListNode[] l1 = new ListNode[mid];
    for(int i=0;i<mid;i++) l1[i] = lists[i];
    ListNode[] l2 = new ListNode[lists.length-mid];
    for(int i=mid,j=0;i<lists.length;i++,j++) l2[j] = lists[i];

进行两两分割和合并:

    return mergeTwoLists(mergeKLists(l1),mergeKLists(l2));

再来定义mergeTwoLists函数,合并两链表可以采用递归也可以采用迭代,这里就不一一解释了:

public ListNode mergeTwoLists(ListNode l1,ListNode l2){//迭代
    if(l1 == null) return l2;
    if(l2 == null) return l1;
    ListNode dummy = new ListNode(-1);
    ListNode cur = dummy;
    while(l1 != null && l2 != null){
        if(l1.val < l2.val){
            cur.next = l1;
            l1 = l1.next;
            cur = cur.next;
        }else{
            cur.next = l2;
            l2 = l2.next;
            cur = cur.next;
        }
    }
    ListNode p = null;
    if(l1 != null){
        p = l1;
    }else if(l2 != null){
        p = l2;
    }else{
        return dummy.next;
    }
    cur.next = p;
    return dummy.next;
}
public ListNode mergeTwoLists(ListNode l1,ListNode l2){//递归
    if(l1 == null) return l2;
    if(l2 == null) return l1;
    ListNode head = null;
    if(l1.val < l2.val){
        head = l1;
        head.next = mergeTwoLists(l1.next,l2);
    }else{
        head = l2;
        head.next = mergeTwoLists(l2.next,l1);
    }
    return head;
}

方法2:还有一种更加简洁的方法,我们可以采用《丑数》的思路,每次从所有链表的头节点开始,比较所有头节点的大小,取出最小的那个,然后被取链表的下一个节点再与其他链表的头节点相比较,直到所有节点比较完,因为我们每次取出最小节点,所以我们可以采用堆来存放这些节点

public ListNode mergeKLists(ListNode[] lists){
    if(lists.length == 0) return null;
    if(lists.length == 1) return lists[0];
    ListNode dummy = new ListNode(-1);
    ListNode cur = dummy;
    PriorityQueue<ListNode> queue = new PriorityQueue<>((head1,head2)->(head1.val-head2.val));
    for(ListNode head : lists){
        if(head == null) continue;
        queue.add(head);
    }
    while(!queue.isEmpty()){
        ListNode head = queue.poll();
        cur.next = head;
        cur = cur.next;
        if(head.next != null) queue.add(head.next);
        cur.next = null;
    }
    return dummy.next;
}

328. 奇偶链表

思路:在这里插入图片描述
这一题挺简单的,但是当时脑袋没有转过来弯想的竟然是直接把偶数节点往队尾差,这样实在太麻烦了,应该直接将链表奇偶分开再连接到尾部即可:

public ListNode oddEvenList(ListNode head) {
    if (head == null) {
        return head;
    }
    ListNode odd = head, even = head.next, evenHead = even;
    while (even != null && even.next != null) {
        odd.next = odd.next.next;
        odd = odd.next;
        even.next = even.next.next;
        even = even.next;
    }
    odd.next = evenHead;
    return head;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值