LeetCode —— Merge k Sorted Lists

  1 /*
  2 ** 算法的思路:
  3 **  1.将k个链表的首元素进行建堆
  4 **  2.从堆中取出最小的元素,放到链表中
  5 **  3.如果取出元素的有后续的元素,则放入堆中,若没有则转步骤2,直到堆为空
  6 */
  7
  8
  9 #include <stdio.h>
 10
 11
 12 struct ListNode
 13 {
 14     int val;
 15     struct ListNode *next;
 16 };
 17
 18
 19 #define PARENT(i) (((i)-1)/2)
 20 #define LEFT(i)    ((i)*2+1)
 21 #define RIGHT(i)    ((i)*2+2)
 22
 23 typedef struct ListNode * ListNodePointer;
 24
 25
 26 void MinHeapify(ListNodePointer lists[], int nListSize, int nParentIndex );
 27 void BuildMinHeap(ListNodePointer lists[], int nListSize );
 28 ListNodePointer ExtractMin( ListNodePointer lists[], int *pListSize );
 29 void InsertHeap(ListNodePointer lists[], int *pListSize, ListNodePointer pNode );
 30 struct ListNode* mergeKLists(struct ListNode** lists, int listsSize);
 31
 32
 33
 34 int main(int argc, char const *argv[])
 35 {
 36
 37     struct ListNode list[2] = {{.next=NULL,.val=2}, {.next=NULL, .val=-1}};
 38     ListNodePointer pListPointerArray[3] = {&list[0], NULL, &list[1]};
 39
 40     ListNodePointer header = mergeKLists(pListPointerArray, 3);
 41
 42     ListNodePointer pList = header;
 43     while( NULL != pList )
 44     {
 45         printf("%d ", pList->val);
 46         pList = pList->next;
 47     }
 48     printf("\n");
 49
 50     return 0;
 51 }
 52
 53
 54
 55 void MinHeapify(ListNodePointer lists[], int nListSize, int nParentIndex )
 56 {
 57
 58     int nLeftIndex;        //左节点下标
 59     int nRightIndex;    //右节点下标
 60     int nMinIndex;        //最小节点下标
 61     ListNodePointer pNodePtrTmp;
 62
 63     do
 64     {
 65         nLeftIndex = LEFT(nParentIndex);
 66         nRightIndex = RIGHT(nParentIndex);
 67         nMinIndex = nParentIndex;
 68
 69         if ( nLeftIndex < nListSize && lists[nLeftIndex]->val < lists[nMinIndex]->val )
 70         {
 71             nMinIndex = nLeftIndex;
 72         }
 73
 74         if ( nRightIndex < nListSize && lists[nRightIndex]->val < lists[nMinIndex]->val )
 75         {
 76             nMinIndex = nRightIndex;
 77         }
 78
 79         if ( nMinIndex != nParentIndex )
 80         {
 81             pNodePtrTmp = lists[nMinIndex];
 82             lists[nMinIndex] = lists[nParentIndex];
 83             lists[nParentIndex] = pNodePtrTmp;
 84
 85             nParentIndex = nMinIndex;
 86
 87         }else
 88         {
 89             break;
 90         }
 91
 92     }while( 1 );
 93 }
 94
 95 //建堆
 96 void BuildMinHeap(ListNodePointer lists[], int nListSize )
 97 {
 98
 99     int i;
100     for ( i = nListSize/2; i >= 0; i-- )
101     {
102         MinHeapify(lists, nListSize, i);
103     }
104 }
105
106 //从堆中取出最小的元素
107 ListNodePointer ExtractMin( ListNodePointer lists[], int *pListSize )
108 {
109
110     ListNodePointer pMinNode = lists[0];
111
112     (*pListSize)--;
113     lists[0] = lists[*pListSize];
114
115     MinHeapify(lists, *pListSize, 0);
116
117     return pMinNode;
118 }
119
120 //向堆中添加元素
121 void InsertHeap(ListNodePointer lists[], int *pListSize, ListNodePointer pNode )
122 {
123
124     int nCurNodeIndex = *pListSize;
125     int nParentIndex = PARENT(nCurNodeIndex);
126     ListNodePointer pNodePtrTmp;
127
128     lists[nCurNodeIndex] = pNode;
129     (*pListSize)++;
130
131     while ( nCurNodeIndex > 0 && lists[nParentIndex]->val > lists[nCurNodeIndex]->val )
132     {
133         pNodePtrTmp = lists[nParentIndex];
134         lists[nParentIndex] = lists[nCurNodeIndex];
135         lists[nCurNodeIndex] = pNodePtrTmp;
136
137         nCurNodeIndex = nParentIndex;
138         nParentIndex = PARENT(nCurNodeIndex);
139     }
140 }
141
142
143 struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
144 {
145
146
147     ListNodePointer *pListPointerArray = (ListNodePointer *) malloc( sizeof(ListNodePointer)*listsSize );
148     struct ListNode header = {.next=NULL};
149     ListNodePointer pTail = NULL;
150
151     int i;
152     int nHeapSize = 0;
153
154     for( i=0; i<listsSize; i++ )
155     {
156         if ( lists[i] != NULL )
157         {
158             pListPointerArray[nHeapSize] = lists[i];
159             nHeapSize++;
160         }
161     }
162
163     if ( nHeapSize == 0 )
164     {
165         return NULL;
166     }
167
168     BuildMinHeap(pListPointerArray, nHeapSize);
169
170     //这里为预处理
171     header.next = ExtractMin(pListPointerArray, &nHeapSize);
172     pTail = header.next;
173     if ( NULL != pTail && pTail->next != NULL )
174     {
175         InsertHeap(pListPointerArray, &nHeapSize, pTail->next );
176     }
177
178     while( nHeapSize != 0 )
179     {
180         pTail->next = ExtractMin(pListPointerArray, &nHeapSize);
181
182         pTail = pTail->next;
183
184         if ( NULL != pTail && NULL != pTail->next )
185         {
186             InsertHeap(pListPointerArray, &nHeapSize, pTail->next );
187         }
188     }
189
190     free(pListPointerArray);
191
192     return header.next;
193 }
时间: 2024-11-04 12:46:42

LeetCode —— Merge k Sorted Lists的相关文章

[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: Merge k Sorted Lists 解题报告

Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Show Tags 参考资料: http://blog.csdn.net/linhuanmars/article/details/19899259. SOLUTION 1: 使用分治法.左右分别递归调用Merge K sorted List,然后再使用merg

[leetcode]Merge k Sorted Lists @ Python [基础知识: heap]

原题地址: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个已经排好序的链表, 使用堆这一数据结构. 堆,也叫做:priority queue 首先将每条链表的头节点进入堆中. 然后将最小的弹出,并将最小的节点这条链

LeetCode -- Merge k Sorted Lists (Divide and Conquer / PriorityQueue)

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 分支策略:每次归并两个已排好序的链表,直至只剩下一个链表. public class Solution { public ListNode mergeKLists(List<ListNode> lists) { //处理特殊情况  if (lists == null)             ret

LeetCode Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { 7 * val = x; 8 * next =

[Leetcode] Merge k sorted lists 合并k个已排序的链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 思路:这题最容易想到的是,(假设有k个链表)链表1.2合并,然后其结果12和3合并,以此类推,最后是123--k-1和k合并.至于两链表合并的过程见merge two sorted lists的分析.复杂度的分析见JustDoIT的博客.算法复杂度:假设每个链表的平均长度是n,则1.2合并,遍历2n个

LeetCode——Merge k Sorted Lists

Discription: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Subscribe to see which companies asked this question. 思路:其实就是归并排序的最后一步归并操作.思想是递归分治,先把一个大问题分成2个子问题,然后对2个子问题的解进行合并.经过一次遍历就能找出已经有序的序列.就算是题目中给

Microsoft leetcode(Merge K Sorted Lists)

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. There are two ways, first use ArrayList to rewrite the linkedlist array, then sort it and use a ListNode to finalize it. public ListNode mergeKLists(Li

LeetCode Merge k Sorted Lists 解决报告

https://oj.leetcode.com/problems/merge-k-sorted-lists/ 归并K已经整理阵列,和分析算法的复杂. 解决报告:无论是不考虑优化,最简单的实现是要重新走路List<ListNode>.对当中每一个链表同当前链表做一遍类似于归并排序最后一步的merge操作. 算法复杂度是O(KN) public class Solution { ListNode mergeTwoLists(ListNode list1, ListNode list2) { Lis