O(N lgK) 时间内合并K个有序链表

来源:互联网 发布:linux 打包压缩文件夹 编辑:程序博客网 时间:2024/04/30 09:34

问题:

在O(N lgK) 时间内合并K个有序链表, 这里N指的是K个链表中所有的元素个数。

分析:

这是一道非常经典的面试题,在很多大公司的面试题中,此题频繁出现。这题也是算法导论的作业题。

这题的思路如下:

1) 在每一个链表中取出第一个值,然后把它们放在一个大小为K的数组里,然后把这个数组当成heap,然后把该堆建成最小堆。此步骤的时间复杂度为O(K)

2 )取出堆中的最小值(也是数组的第一个值),然后把该最小值所处的链表的下一个值放在数组的第一个位置。如果链表中有一个已经为空(元素已经都被取出),则改变heap的大小。然后,执行MIN-HEAPIFY操作,此步骤的时间复杂度为O(lg K).

3 ) 不断的重复步骤二,直到所有的链表都为空。

代码如下:

[java] view plaincopy
  1. public void minHeapify(Node[] node, int index, int size) {  
  2.     int left = 2 * index + 1;  
  3.     int right = 2 * index + 2;  
  4.     int smallest;  
  5.       
  6.     if (left < size && node[left].data < node[index].data) {  
  7.         smallest = left;  
  8.     } else {  
  9.         smallest = index;  
  10.     }  
  11.       
  12.     if (right < size && node[right].data < node[smallest].data) {  
  13.         smallest = right;  
  14.     }  
  15.       
  16.     if (smallest != index) {  
  17.         exchange(node, smallest, index);  
  18.         minHeapify(node, smallest, size);  
  19.     }  
  20. }  
创建最小堆:

[java] view plaincopy
  1. public void buildMinHeap(Node[] node, int size) {  
  2.     for (int i = size / 2 - 1; i >= 0; i--) {  
  3.         minHeapify(node, i, size);  
  4.     }  
  5. }  
合并:

[java] view plaincopy
  1. public Node mergeKSortedList(Node[] heads) {  
  2.         Node head = null// the head of the merged list  
  3.         Node current = null;  
  4.         int size = heads.length;  
  5.         Node[] heap = new Node[heads.length]; // create a heap  
  6.         // initialize the value of the heap  
  7.         for (int i = 0; i < heads.length; i++) {  
  8.             heap[i] = heads[i];  
  9.             heads[i] = heads[i].next;  
  10.         }  
  11.         // create a min heap  
  12.         buildMinHeap(heap, size);  
  13.           
  14.         int tempSize = size;  
  15.         while (size > 0) {  
  16.             if (head == null) {  
  17.                 head = heap[0];  
  18.                 current = head;  
  19.             } else {  
  20.                 current.next = heap[0];  
  21.                 current = current.next;  
  22.             }  
  23.             if (heap[0].next == null) {  
  24.                 size--;  
  25.             } else {  
  26.                 heap[0] = heap[0].next;  
  27.             }  
  28.               
  29.             // if the size of heap changes, we need to move all the elements in the heap to  
  30.             // the front of the heap  
  31.             if (size != tempSize) {  
  32.                 for (int i = 0; i < size; i++) {  
  33.                     heap[i] = heap[i+1];  
  34.                 }  
  35.                 tempSize = size;  
  36.             }  
  37.             minHeapify(heap, 0, size);  
  38.         }  
  39.         return head;  
  40.     }  
0 0
原创粉丝点击