合並 k 個排序鏈表,返回合並后的排序鏈表。請分析和描述算法的復雜度。
示例:
輸入: [ 1->4->5, 1->3->4, 2->6 ] 輸出: 1->1->2->3->4->4->5->6
思路:k個鏈表是排好序的,那我們就可以依次,按順序的比較每個鏈表的節點,將最小的依次放入一個新鏈表中。我的做法是動態申請一個指針數組,每個鏈表均由一個指針指向,然后就可以比較每個鏈表的值,直到每個鏈表為空。這里注意在遍歷的時候要注意判斷是否為空,否則就會出現一個鏈表為零,還在比較它的節點大小的情況,訪問出錯。
ListNode* mergeKLists(vector<ListNode*>& lists) { ListNode* newhead=new ListNode(0); ListNode* cur=newhead; int len=lists.size(); if(len==0) return NULL; ListNode** p=new ListNode*[len]; for(int i=0;i<len;i++) { p[i]=lists[i]; } while(cur) { int pos=0; int min=INT_MAX; for(int i=0;i<len;i++) { if(p[i]&&min>p[i]->val )//找到最小的節點,並記錄鏈表的下標 { pos=i; min=p[i]->val; } } if(p[pos])//不為空掛在后面,否則意味着全為空了,退出 { cur->next=new ListNode(p[pos]->val); p[pos]=p[pos]->next; cur=cur->next; } else break; } return newhead->next; }
其實我們可以用優先隊列來完成找最小節點的任務。
struct cmp { bool operator() (const ListNode* a, const ListNode* b) { return a->val > b->val; } }; class Solution { public: ListNode* mergeKLists(vector<ListNode*>& lists) { priority_queue<ListNode*, vector<ListNode*>, cmp> heap; ListNode *head = new ListNode(0); ListNode *curr = head; auto iter = lists.begin(); for (; iter != lists.end(); iter++) { if (*iter != NULL) { heap.push(*iter); } } while (!heap.empty()) { ListNode* minNode = heap.top(); heap.pop(); ListNode* tmp = new ListNode(minNode->val); curr->next = tmp; curr = curr->next; if (minNode->next != NULL) { heap.push(minNode->next); } } return head->next; } };