leetcode-23-合并K个排序链表-java

题目及测试

package pid023;
/*  合并K个元素的有序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6


*/
public class main {
	
public static void main(String[] args) {
		
		LinkList a=new LinkList(1);
		a.addLast(4);
		a.addLast(5);
		a.printList();
		
		LinkList b=new LinkList(1);
		b.addLast(3);
		b.addLast(4);
		b.printList();
		
		LinkList c=new LinkList(2);
		c.addLast(6);
		c.printList();
		
		ListNode[] listNodes=new ListNode[]{a.first,b.first,c.first};
		test(listNodes);
	}
		 
	private static void test(ListNode[] ito) {
		Solution solution = new Solution();
		ListNode rtn;
		long begin = System.currentTimeMillis();
		System.out.println();
		//开始时打印数组
		
		rtn=solution.mergeKLists(ito);//执行程序
		long end = System.currentTimeMillis();	
		System.out.println("rtn=");
		rtn.printNodeToEnd();
		
		//System.out.println(":rtn" );
		//System.out.print(rtn);
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,471ms,极慢)

比较 k个节点(每个链表的首节点),获得最小值的节点。
将选中的节点接在最终有序链表的后面。

时间复杂度: O(kN),其中 k是链表的数目。

 

package pid023;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

import pid116.Node;
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
	public ListNode mergeKLists(ListNode[] lists) {
	    int length=lists.length;
	    if(length==0){
	    	return null;
	    }
	    if(length==1){
	    	return lists[0];
	    }
	    ListNode first=new ListNode(0);
	    ListNode now=first;
	    while(true){
	    	int min=Integer.MAX_VALUE;
	    	int minIndex=-1;
	    	for(int i=0;i<length;i++){
		    	if(lists[i]!=null&&min>=lists[i].val){
		    		min=lists[i].val;
		    		minIndex=i;
		    	}		    	
		    }
	    	if(minIndex==-1){
	    		break;
	    	}else{
	    		now.next=lists[minIndex];
	    		now=now.next;
	    		lists[minIndex]=lists[minIndex].next;
	    	}	    	
	    }	    		
		return first.next;
    }
}

解法2(别人的)

使用优先级队列,PriorityQueue

时间复杂度:O(n∗log(k)),n 是所有链表中元素的总和,k 是链表个数。

class Solution {
   public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        PriorityQueue<ListNode> queue = new PriorityQueue<>(lists.length, new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                if (o1.val < o2.val) return -1;
                else if (o1.val == o2.val) return 0;
                else return 1;
            }
        });
        ListNode dummy = new ListNode(0);
        ListNode p = dummy;
        for (ListNode node : lists) {
            if (node != null) queue.add(node);
        }
        while (!queue.isEmpty()) {
            p.next = queue.poll();
            p = p.next;
            if (p.next != null) queue.add(p.next);
        }
        return dummy.next;
    }
}

解法3(成功,9ms,较慢)

优先队列能传入的参数有index,ListNode,val,可以只传入ListNode,因为它包含了val,并且还有next,能够定位当前节点和下一个节点。如果传入index,可以用Pair<val,index>。

	public ListNode mergeKLists(ListNode[] lists) {
	    int length=lists.length;
	    if(length==0){
	    	return null;
	    }
	    if(length==1){
	    	return lists[0];
	    }
	    ListNode first=new ListNode(0);
	    ListNode now=first;
	    Comparator<Pair<Integer, Integer>> compartor = new Comparator<Pair<Integer, Integer>>() {
			@Override
			public int compare(Pair<Integer, Integer> o1, Pair<Integer, Integer> o2) {
				return o1.getKey() - o2.getKey();
			}
	    	
		};
	    PriorityQueue<Pair<Integer, Integer>> queue = new PriorityQueue<Pair<Integer,Integer>>(compartor);
	    for(int i=0;i<length;i++) {
	    	if(lists[i] != null) {
	    		queue.add(new Pair<Integer, Integer>(lists[i].val, i));
	    	}	    	
	    }
	    
	    while(true){
	    	if(queue.isEmpty()) {
	    		break;
	    	}else {
	    		Pair<Integer, Integer> pair = queue.poll();
	    		int index = pair.getValue();
	    		now.next = lists[index];
	    		now = now.next;
	    		lists[index] = lists[index].next;
	    		if(lists[index] != null) {
	    			queue.add(new Pair<Integer, Integer>(lists[index].val, index));
	    		}
	    	}
	    }	    		
		return first.next;
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值