合并多个有序链表

来源:互联网 发布:nba2kol乔丹隐藏数据 编辑:程序博客网 时间:2024/06/01 09:20

1、维持一个最小堆,利用堆的性质每次从堆中取出一个最小值加入node中。

import java.util.ArrayList;import java.util.List;public class MergeKList {    public static void main(String[] args) {        // TODO Auto-generated method stub        ListNode node11 = new ListNode(1);        ListNode node12 = new ListNode(3);        ListNode node13 = new ListNode(5);        ListNode node14 = new ListNode(7);        node11.next = node12;        node12.next = node13;        node13.next = node14;        ListNode node21 = new ListNode(1);        ListNode node22 = new ListNode(2);        ListNode node23 = new ListNode(3);        node21.next = node22;        node22.next = node23;        ListNode node33 = new ListNode(3);        ListNode node34 = new ListNode(4);        node33.next = node34;        ListNode list[] = { node11, node21, node33,null};        ListNode head = mergeK(list);        while (head != null) {            System.out.println(head.val);            head = head.next;        }    }    public static ListNode mergeKLists(ListNode[] list) {        // delete null node        ListNode[] noEmpty=new ListNode[list.length];        int k=0;        for(int i=0;i<list.length;i++){            if(list[i]!=null)noEmpty[k++]=list[i];        }        if(k==0)return null;        if(k==1)return noEmpty[0];        ListNode head = null;        List<Integer> val = new ArrayList<Integer>();        int i = 0;        buildHead(noEmpty,k);        print("build heap:", list,k);        head = getOneNode(noEmpty, val,k);        ListNode temp = head;        while (temp != null) {            temp.next = getOneNode(noEmpty, val,k);            temp = temp.next;        }        // restore        temp = head;        while (temp != null) {            if (temp.val == Integer.MAX_VALUE)                temp.val = val.get(i++);            temp = temp.next;        }        return head;    }    // get one node from heap,the first is the minValue.    public static ListNode getOneNode(ListNode[] list, List<Integer> val,int k) {        ListNode node = list[0];        if (node.val == Integer.MAX_VALUE)            return null;        if (node.next != null) {            list[0] = node.next;        } else {            val.add(list[0].val);            list[0].val = Integer.MAX_VALUE;        }        adjustHeap(list, 0,k);        print("AftergetOne:", list,k);        return node;    }    public static void adjustHeap(ListNode[] list, int start,int k) {        int left = 0, right = 0;        int min = start;        left = start * 2 + 1;        right = start * 2 + 2;        if(left<k&&list[left].val<list[min].val){            min=left;        }        if(right<k&&list[right].val<list[min].val){            min=right;        }        if (min!=start) {            ListNode temp = list[min];            list[min] = list[start];            list[start] = temp;            adjustHeap(list, min,k);        }    }    // build a minHeadp    public static void buildHead(ListNode[] list,int k) {        for (int i = k/2; i >=0; i--) {            adjustHeap(list, i,k);        }    }    public static void print(String str, ListNode[] list,int k) {        System.out.print(str);        for (int i = 0; i < k; i++) {            System.out.print(list[i].val + " ");        }        System.out.println();    }}

2、利用优先队列,非常简单。

public static ListNode mergeKLists(ListNode[] lists) {        Queue<ListNode> queue = new PriorityQueue<ListNode>(                new Comparator<ListNode>() {                    @Override                    public int compare(ListNode arg0, ListNode arg1) {                        return arg0.val - arg1.val;                    }                });        for (ListNode node : lists) {            if (node != null) {                queue.add(node);            }        }        ListNode head = new ListNode(0), p = head, cur = null;        while( !queue.isEmpty()) {            cur = queue.poll();            if(cur.next!=null)queue.offer(cur.next);            p.next = cur;            p = p.next;        }        return head.next;    }

3、递归,每次将数组二分,求出二分后每一块的ListNode,然后合并这两块。

public static ListNode mergeKLists(ListNode[] lists){    return partion(lists,0,lists.length-1);}public static ListNode partion(ListNode[] lists,int s,int e){    if(s==e)  return lists[s];    if(s<e){        int q=s+(e-s)/2;        ListNode l1=partion(lists,s,q);        ListNode l2=partion(lists,q+1,e);        return merge(l1,l2);    }else        return null;}//This function is from Merge Two Sorted Lists.public static ListNode merge(ListNode l1,ListNode l2){    if(l1==null) return l2;    if(l2==null) return l1;    if(l1.val<l2.val){        l1.next=merge(l1.next,l2);        return l1;    }else{        l2.next=merge(l1,l2.next);        return l2;    }}
0 0