zoukankan      html  css  js  c++  java
  • 图解算法——合并k个排序列表(Merge k Sorted Lists)

    1. 题目描述

    You are given an array of k linked-lists lists, each linked-list is sorted in ascending order.
    Merge all the linked-lists into one sorted linked-list and return it.

    翻译:

    给定一个链表长度为k的链表数组,每个链表按升序排序。

    将数组中所有的链表合并为一个有序的链表,并返回它。

    2.示例

    示例1:

    Input: lists = [[1,4,5],[1,3,4],[2,6]]
    Output: [1,1,2,3,4,4,5,6]
    Explanation: The linked-lists are:
    [
      1->4->5,
      1->3->4,
      2->6
    ]
    merging them into one sorted list:
    1->1->2->3->4->4->5->6

    示例2:

    Input: lists = []
    Output: []

    示例3:

    Input: lists = [[]]
    Output: []

    3.要求

    • k == lists.length

    • 0 <= k <= 10^4

    • 0 <= lists[i].length <= 500

    • -10^4 <= lists[i][j] <= 10^4

    • lists[i] is sorted in ascending order.

    • The sum of lists[i].length won't exceed 10^4.

    4. 题目解析

    其实,这个题目和归并排序有相似之处。归并排序是一个数组(也可以看做是两个数组哈)的排序,而这个题目是多个;

    归并排序中原数组不一定是有序的,而这里的数组都是按照升序排列的。

    合并k个有序list,有递归和非递归两种解法,

    思路:递归:

    就是先新建一个链表,然后用该链表和整个链表数组中的每一个链表进行两两结合。

    */
    /*
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode mergeKLists(ListNode[] lists) {
            if(lists==null || lists.length<=0
                || lists[0]==null || lists[0].length<=0){
                return null;
            }
            
            ListNode head = null;//新建的链表头结点
            for(int i = 0; i<lists.length;i++){
                ListNode listnode = lists[i];  //取出数组中的每一个链表
                head = merge2Link(head,listnode);//合并
            }
            return head;
        }
        
        public ListNode merge2Link(ListNode head, ListNode tail){
            if(tail == null)
                return head;
            if(head == null)
                return tail;
            
            if(head.val < tail.val){
                head.next = merge2Link(head.next,tail);//递归
                return head;
            }else{
                tail.next = merge2Link(head,tail.next);//递归
                return tail;
            }
        }
    }

    非递归思路:

    和上述思路一致,都是两两合并,只不过重写了merge2Link()方法,不是递归的思路,如下:

        /*
        接下来就用到归并排序思想了
        */
        public ListNode merge2Link(ListNode node1, ListNode node2){
            ListNode res = new ListNode(0);//返回时,将res.next返回 
            ListNode head = res;//中间指针变量,下面的循环用到的是这个指针
            while(node1!=null && node2!=null){
                if(node1.val<node2.val){
                    head.next = node1;
                    node1 = node1.next;
                }else{
                    head.next = node2;
                    node2 = node2.next;
                }
                head = head.next;
            }
            while(node1!=null){
                head.next = node1;
            }
            while(node2!=null){
                head.next = node2;
            }
            return res.next;
        }

    Over......

  • 相关阅读:
    设计模式学习(十二) 责任链模式
    设计模式学习(十一) 享元模式
    设计模式学习(十) 外观模式
    设计模式学习(九) 装饰模式
    设计模式学习(八) 组合模式
    设计模式学习(七) 桥接模式
    设计模式学习(六) 代理模式
    设计模式学习(五) 适配器模式
    设计模式学习(四) 原型模型
    设计模式(三) 建造者模式
  • 原文地址:https://www.cnblogs.com/gjmhome/p/14406726.html
Copyright © 2011-2022 走看看