Merge k Sorted Lists, k路归并

import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
/*
class ListNode
{
    ListNode next;
    int val;
    ListNode(int x)
    {
        val = x;
    }
}
*/
//k路归并问题
public class MergKSortedLists {

    //二路归并,这个算法时间复杂度o(2n)
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dumy = new ListNode(0);
        ListNode head = dumy;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                dumy.next = l1;
                l1 = l1.next;
            } else {
                dumy.next = l2;
                l2 = l2.next;
            }
            dumy = dumy.next;
        }
        if (l1 == null) {
            dumy.next = l2;
        }
        if (l2 == null) {
            dumy.next = l1;
        }
        return head.next;
    }
    //利用二路归并进行k路归并,时间复杂度o(2kn),leetcode显示time limits exceeds
    public ListNode mergeKLists1(ListNode[] lists)
    {
        if(lists.length == 0)
        {
            return null;
        }
        ListNode head = lists[0];
        for(int i = 1; i < lists.length; i ++)
        {
            head = mergeTwoLists(head, lists[i]);
        }
        return head;
    }

    //网上看到的很有意思的想法。就把ListNode当做一个整数,这道题,正好看做数组的二路归并排序,不过数组里面的元素是节点
    //这种方法显然也是超时的,这种思想,看似是二路归并,其实并不是,粒度不一样。这个算法的时间复杂度也并不是O(nlgn)
    public ListNode mergerKlists2(ListNode[] lists)
    {
        //自顶向下的二路归并,递归
        if(lists.length == 0)
        {
            return null;
        }
        List<ListNode> a = Arrays.asList(lists);
        return helper(a);
    }
    public ListNode helper(List<ListNode> lists)
    {
        if(lists.size() == 1)
        {
            return lists.get(0);
        }
        int len = lists.size();
        int mid = len/2;
        ListNode l1 = helper(lists.subList(0, mid));
        ListNode l2 = helper(lists.subList(mid, len));
        return mergeTwoLists(l1, l2);
    }

    //利用PriorityQueue的特性,也很巧妙,并且AC
    //算法思想是:比较所有k个数组的头一个元素,找到最小的那一个,然后取出来。
    //我们在该最小元素所在的数组取下一个元素,然后重复前面的过程去找最小的那个。这样依次循环直到找到所有的元素。
    public ListNode mergeKLists3(ListNode[] lists)
    {
        if(lists.length == 0)
            return null;
        //由于ListNode并没有实现comparable接口,我们必须自定义排序规则,可实现comparator接口,comparator是函数式接口
        //comparable接口是在方法内的,而comparator接口是在方法外的注意区别两者
        PriorityQueue<ListNode> queue = new PriorityQueue<>((o1, o2)->
        {
            ListNode l1 = (ListNode)o1;
            ListNode l2 = (ListNode)o2;
            return l1.val > l2.val ? 1 : l1.val < l2.val ? -1 : 0;
        });
        ListNode head = new ListNode(0);
        ListNode p = head;
        for (ListNode list : lists) {
            queue.offer(list);
        }
        while(!queue.isEmpty())
        {
            ListNode n = queue.poll();
            p.next = n;
            p = p.next;
            if(n.next!=null)
            {
                queue.offer(n.next);
            }
        }
        return head.next;
    }
}

堆排序算法后续补充。。。。

时间: 2024-10-13 16:00:36

Merge k Sorted Lists, k路归并的相关文章

#23 Merge k Sorted Lists (N路归并排序)

#23 Merge k Sorted Lists (N路归并排序) 题目地址:#23 题目分类:链表/归并排序/堆排序 题目难度:hard 题目 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 翻译:合并K个已经排序的链表,返回一个排序好的链表. 思路 暴力法,我们很容易想到:以一个for循环遍历所有的链表,找出最小的,然后将这个节点加入新的链表

leetcode 刷题之路 93 Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 将k个有序链表合并成一个有序链表. 思路,之前做过两个有序链表的合并操作,对于k个链表,我们最先想到的就是能不能转化为我们熟悉的两个链表的合并,可以我们先将k个链表分为两部分,先对这两部分完成链表的有序合并操作,再对合并得到的两个链表进行合并,这是一个递归性质的描述,采用递归很容易实现这个程序,和数组

【LeetCode】【数组归并】Merge k Sorted Lists

描述 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Example: Input: [   1->4->5,   1->3->4,   2->6 ] Output: 1->1->2->3->4->4->5->6 思路 借鉴Merge Two Sorted Lists的解决思路,对两个数

Leetcode 23.Merge Two Sorted Lists Merge K Sorted Lists

Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 依次拼接 复杂度 时间 O(N) 空间 O(1) 思路 该题就是简单的把两个链表的节点拼接起来,我们可以用一个Dummy头,将比较过后的节点接在这个Dummy头之后.最后

[leetcode]Merge k Sorted Lists @ Python

原题地址:https://oj.leetcode.com/problems/merge-k-sorted-lists/ 题意:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 解题思路:归并k个已经排好序的链表.使用堆这一数据结构,首先将每条链表的头节点进入堆中,然后将最小的弹出,并将最小的节点这条链表的下一个节点入堆,依次类推,最终形成的链表就是归

LeetCode: Merge k Sorted Lists [022]

[题目] Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. [题意] 合并K个有序链表 [思路] 归并 [代码] /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), n

leetCode 23. Merge k Sorted Lists (合并k个排序链表) 解题思路和方法

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:此题是由合并两个排序链表演化而来,刚开始,想法比较简单,像求最大公共前缀一样,逐一求解:但是最后超时,所以马上意识到出题方是为了使用归并和分治的方法,故重新写了代码. 代码一(超时未过): /** * Definition for singly-link

[LeetCode 题解]: Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题意:对k个有序的链表进行归并排序.并分析其复杂度. /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(N

Merge k Sorted Lists leetcode java

题目: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题解: Merge k sorted linked list就是merge 2 sorted linked list的变形题. 而且我们很自然的就想到了经典的Merge Sort,只不过那个是对数组进行sort.而不同的地方,仅仅是Merge两个list的操作不同. 这里来复习一下Merge