当前位置:   article > 正文

牛客-C语言解法-合并k个已排序的链表_c语言合并 n 个升序的链表并将结果作为一个升序的链表返回 数据范围:节点总数 0≤

c语言合并 n 个升序的链表并将结果作为一个升序的链表返回 数据范围:节点总数 0≤

 题目链接:

合并k个已排序的链表_牛客题霸_牛客网 (nowcoder.com)

题目简介:

描述

合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。

数据范围:节点总数 0≤n≤5000,每个节点的val满足 ∣val∣<=1000

要求:时间复杂度 O(nlogn)

题目解法:

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. /*
  4. *BM5 合并k个已排序的链表
  5. 描述
  6. 合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
  7. 数据范围:节点总数 0≤n≤5000,每个节点的val满足 |val| <= 1000
  8. 要求:时间复杂度 O(nlogn)O(nlogn)
  9. 如输入[{1,2,3},{4,5,6,7}]时,返回{1,2,3,4,5,6,7},
  10. */
  11. /**************************code*****************************************/
  12. struct ListNode {
  13. int val;
  14. struct ListNode *next;
  15. };
  16. /**
  17. *
  18. * @param lists ListNode类一维数组
  19. * @param listsLen int lists数组长度
  20. * @return ListNode类
  21. */
  22. //根据索引获得链表的元素
  23. int getListElemByIndex(struct ListNode* list, int index){
  24. for(int i=0; i<index; i++)
  25. list = list->next;
  26. return list->val;
  27. }
  28. //计算数组指定长度的前N项和
  29. int getSumLen(int *eachLen, int listsLen){
  30. int sumLen = 0;
  31. for(int i=0; i<listsLen; i++){
  32. sumLen += eachLen[i];
  33. }
  34. return sumLen;
  35. }
  36. //找到链表首部最小的值,并返回链表索引
  37. int findListHeadMin(struct ListNode** lists, int listsLen, int* eachIndex, int* eachLen){
  38. int listIndex = 0;
  39. int listNodeMin = 1001;
  40. int tmpVal;
  41. struct ListNode* tmpList;
  42. for(int i=0; i<listsLen; i++){
  43. if(eachIndex[i] >= eachLen[i])continue; //如果该链表已经用完,跳过
  44. tmpVal = getListElemByIndex(lists[i], eachIndex[i]);
  45. if(tmpVal < listNodeMin){
  46. listNodeMin = tmpVal;
  47. listIndex = i;
  48. }
  49. }
  50. return listIndex;
  51. }
  52. struct ListNode* mergeKLists(struct ListNode** lists, int listsLen ) {
  53. // write code here
  54. struct ListNode* dummyHead = (struct ListNode*)malloc(sizeof(struct ListNode));
  55. struct ListNode* tmpNode = dummyHead;
  56. int *eachLen = (int*)malloc(sizeof(int)*listsLen); //保存各个链表的长度
  57. int *eachIndex = (int*)malloc(sizeof(int)*listsLen); //保存各个链表的索引
  58. int sumLen = 0;//各个链表相加的总长度
  59. int listMinIndex; //各个链表中当前节点值最小的链表索引
  60. for(int i=0; i<listsLen; i++){ //获得各个链表的长度
  61. int len = 0;
  62. eachLen[i] = 0;
  63. eachIndex[i] = 0; //清空索引
  64. struct ListNode* tmp = *(lists + i);
  65. while(tmp){
  66. eachLen[i]++;
  67. tmp = tmp->next;
  68. }
  69. }
  70. sumLen = getSumLen(eachLen, listsLen); //计算各个链表的元素总和
  71. if(sumLen == 0) return NULL; //如果 0个链表 或者 有多个链表但每个链表都为空,则返回NULL
  72. for(int curLen=0; curLen<sumLen; curLen++){ //根据元素总和进行循环
  73. tmpNode->val = 0; //先初始化当前链表值
  74. listMinIndex = findListHeadMin(lists, listsLen, eachIndex, eachLen); //找到各个链表中未使用的首元素最小的链表索引
  75. tmpNode->val = getListElemByIndex(lists[listMinIndex], eachIndex[listMinIndex]); //根据链表以及链表索引找到未使用的元素
  76. eachIndex[listMinIndex]++; //记录当前链表已使用的元素数量,方便findListHeadMin函数判断未使用的元素以及是否到末尾了
  77. if(curLen==sumLen-1)continue; //如果已经到最后一个元素,那么不再申请节点
  78. tmpNode->next = (struct ListNode*)malloc(sizeof(struct ListNode)); //初始化新节点
  79. tmpNode = tmpNode->next; //指向下一个节点
  80. }
  81. return dummyHead;
  82. }
  83. /**************************end******************************************/
  84. int main ()
  85. {
  86. struct ListNode LN13={3,NULL};
  87. struct ListNode LN12={2,&LN13};
  88. struct ListNode LN1 ={1,&LN12};
  89. struct ListNode LN24={7,NULL};
  90. struct ListNode LN23={6,&LN24};
  91. struct ListNode LN22={5,&LN23};
  92. struct ListNode LN2 ={4,&LN22};
  93. struct ListNode *input1[2] = {&LN1, &LN2};
  94. struct ListNode LN33={3,NULL};
  95. struct ListNode LN32={2,&LN33};
  96. struct ListNode LN3 ={1,&LN32};
  97. struct ListNode LN43={3,NULL};
  98. struct ListNode LN42={3,&LN43};
  99. struct ListNode LN4 ={3,&LN42};
  100. struct ListNode *pLN = mergeKLists(input1, 2);
  101. return 0;
  102. }

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号