赞
踩
合并k个已排序的链表_牛客题霸_牛客网 (nowcoder.com)
描述
合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
数据范围:节点总数 0≤n≤5000,每个节点的val满足 ∣val∣<=1000
要求:时间复杂度 O(nlogn)
- #include "stdio.h"
- #include "stdlib.h"
-
-
- /*
- *BM5 合并k个已排序的链表
- 描述
- 合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
- 数据范围:节点总数 0≤n≤5000,每个节点的val满足 |val| <= 1000
- 要求:时间复杂度 O(nlogn)O(nlogn)
- 如输入[{1,2,3},{4,5,6,7}]时,返回{1,2,3,4,5,6,7},
- */
-
- /**************************code*****************************************/
- struct ListNode {
- int val;
- struct ListNode *next;
- };
-
- /**
- *
- * @param lists ListNode类一维数组
- * @param listsLen int lists数组长度
- * @return ListNode类
- */
- //根据索引获得链表的元素
- int getListElemByIndex(struct ListNode* list, int index){
- for(int i=0; i<index; i++)
- list = list->next;
- return list->val;
- }
-
- //计算数组指定长度的前N项和
- int getSumLen(int *eachLen, int listsLen){
- int sumLen = 0;
- for(int i=0; i<listsLen; i++){
- sumLen += eachLen[i];
- }
- return sumLen;
- }
- //找到链表首部最小的值,并返回链表索引
- int findListHeadMin(struct ListNode** lists, int listsLen, int* eachIndex, int* eachLen){
- int listIndex = 0;
- int listNodeMin = 1001;
- int tmpVal;
- struct ListNode* tmpList;
- for(int i=0; i<listsLen; i++){
- if(eachIndex[i] >= eachLen[i])continue; //如果该链表已经用完,跳过
-
- tmpVal = getListElemByIndex(lists[i], eachIndex[i]);
- if(tmpVal < listNodeMin){
- listNodeMin = tmpVal;
- listIndex = i;
- }
- }
- return listIndex;
- }
-
- struct ListNode* mergeKLists(struct ListNode** lists, int listsLen ) {
- // write code here
- struct ListNode* dummyHead = (struct ListNode*)malloc(sizeof(struct ListNode));
- struct ListNode* tmpNode = dummyHead;
- int *eachLen = (int*)malloc(sizeof(int)*listsLen); //保存各个链表的长度
- int *eachIndex = (int*)malloc(sizeof(int)*listsLen); //保存各个链表的索引
- int sumLen = 0;//各个链表相加的总长度
- int listMinIndex; //各个链表中当前节点值最小的链表索引
-
- for(int i=0; i<listsLen; i++){ //获得各个链表的长度
- int len = 0;
- eachLen[i] = 0;
- eachIndex[i] = 0; //清空索引
- struct ListNode* tmp = *(lists + i);
- while(tmp){
- eachLen[i]++;
- tmp = tmp->next;
- }
- }
- sumLen = getSumLen(eachLen, listsLen); //计算各个链表的元素总和
- if(sumLen == 0) return NULL; //如果 0个链表 或者 有多个链表但每个链表都为空,则返回NULL
- for(int curLen=0; curLen<sumLen; curLen++){ //根据元素总和进行循环
- tmpNode->val = 0; //先初始化当前链表值
-
- listMinIndex = findListHeadMin(lists, listsLen, eachIndex, eachLen); //找到各个链表中未使用的首元素最小的链表索引
- tmpNode->val = getListElemByIndex(lists[listMinIndex], eachIndex[listMinIndex]); //根据链表以及链表索引找到未使用的元素
- eachIndex[listMinIndex]++; //记录当前链表已使用的元素数量,方便findListHeadMin函数判断未使用的元素以及是否到末尾了
-
- if(curLen==sumLen-1)continue; //如果已经到最后一个元素,那么不再申请节点
- tmpNode->next = (struct ListNode*)malloc(sizeof(struct ListNode)); //初始化新节点
- tmpNode = tmpNode->next; //指向下一个节点
- }
-
- return dummyHead;
- }
-
- /**************************end******************************************/
-
- int main ()
- {
- struct ListNode LN13={3,NULL};
- struct ListNode LN12={2,&LN13};
- struct ListNode LN1 ={1,&LN12};
-
- struct ListNode LN24={7,NULL};
- struct ListNode LN23={6,&LN24};
- struct ListNode LN22={5,&LN23};
- struct ListNode LN2 ={4,&LN22};
- struct ListNode *input1[2] = {&LN1, &LN2};
-
- struct ListNode LN33={3,NULL};
- struct ListNode LN32={2,&LN33};
- struct ListNode LN3 ={1,&LN32};
-
- struct ListNode LN43={3,NULL};
- struct ListNode LN42={3,&LN43};
- struct ListNode LN4 ={3,&LN42};
-
- struct ListNode *pLN = mergeKLists(input1, 2);
-
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。