https://oj.leetcode.com/problems/merge-k-sorted-lists/
这道题主要是考虑测试数据的特点吧。
刚开始的时候想,每次找出头结点中最小的两个,然后取最小的一个,一直取到它的值 > 倒数第二小的,之后重复这个过程。
适合的数据特点为: 1 2 3 5 6 7 10 20
11 12 15 18 …… 这样子的
于是写出了代码,但是超时了。
超时的数据是这样的:[{7},{49},{73},{58},{30},{72},{44},{78},{23},{9},{40},{65},{92},{42},{87},{3},{27},{29},{40},……
也就是每个链表长度为1,这样的话,就多了好多去两个最小值的操作。
于是参考了答案,方法是每次合并两个链表,得到一个新链表,之后新链表再和下一个合并……
代码分别如下:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *mergeKLists(vector<ListNode *> &lists) { ListNode *dummy = new ListNode(0); if(lists.size() == 0) return dummy->next; int count = 0; // record null number int small = 0; int bigger = 0; int smallestIndex = 0; int biggerIndex = 0; ListNode *currentNode = dummy; for(int i = 0; i < lists.size(); i++) { if(lists[i] == NULL) count++; } while(count < lists.size() - 1) { findTwoLittle(lists,smallestIndex,biggerIndex); currentNode->next = lists[smallestIndex]; while(lists[smallestIndex]->next != NULL &&lists[smallestIndex]->next->val <= lists[biggerIndex]->val) { lists[smallestIndex] = lists[smallestIndex]->next; } currentNode = lists[smallestIndex]; lists[smallestIndex] = lists[smallestIndex]->next; if(lists[smallestIndex] == NULL) count++; } // only one isn't null for(int i = 0; i < lists.size(); i++) { if(lists[i] != NULL) { currentNode->next = lists[i]; break; } } return dummy->next; } //至少还有两个元素的时候 void findTwoLittle(vector<ListNode *> &lists, int &smallestIndex, int &biggerIndex) { int small = INT16_MAX; int bigger = INT16_MAX; smallestIndex = 0; biggerIndex = 0; for(int i = 0; i < lists.size(); i++) { if(lists[i] != NULL) { if(lists[i]->val <= small) { bigger = small; small = lists[i]->val; biggerIndex = smallestIndex; smallestIndex = i; } else if(lists[i]->val > bigger) continue; else { bigger = lists[i]->val; biggerIndex = i; } } } } };
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *mergeKLists(vector<ListNode *> &lists) { if(lists.size() == 0) return NULL; ListNode *p = lists[0]; for(int i = 1; i < lists.size(); i++) p = mergeTwoLists(p,lists[i]); return p; } ListNode *mergeTwoLists(ListNode *l1,ListNode *l2){ ListNode head(-1); for(ListNode *p = &head; l1 != NULL || l2 != NULL; p = p->next) { int val1 = l1 == NULL? INT_MAX:l1->val; int val2 = l2 == NULL? INT_MAX:l2->val; if(val1 <= val2) { p->next = l1; l1 = l1->next; } else { p->next = l2; l2 = l2->next; } } return head.next; } };