腾讯//合并K个排序链表
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1->1->2->3->4->4->5->6
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode result = new ListNode(0);
ListNode point = result;
List<Integer> list = new ArrayList<Integer>();
for(ListNode node:lists){
while(node != null){
list.add(node.val);
node = node.next;
}
}
Collections.sort(list);
for(int x:list){
point.next = new ListNode(x);
point = point.next;
}
return result.next;
}
}
找寻出K个链表中的最小节点,并将其从K个链表集中剔除,再将其添加到新的链表中,直到K个链表都为空为止。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode result = new ListNode(0);
ListNode point = result;
while(true){
int min_val = Integer.MAX_VALUE;
int position = -1;
for(int i = 0; i < lists.length; i++){
if(lists[i] != null){
if(lists[i].val < min_val){
min_val = lists[i].val;
position = i;
}
}
}
if(min_val == Integer.MAX_VALUE)
break;
point.next = new ListNode(min_val);
point = point.next;
lists[position] = lists[position].next;
}
return result.next;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists){
ListNode result = new ListNode(0);
ListNode point = result;
PriorityQueue<ListNode> q = new PriorityQueue<>(valComparator);
for(ListNode node:lists){
if(node!=null){
q.add(node);
}
}
while(!q.isEmpty()){
ListNode current_node = q.poll();
point.next = new ListNode(current_node.val);
point = point.next;
current_node = current_node.next;
if(current_node!=null){
q.add(current_node);
}
}
return result.next;
}
private static Comparator<ListNode> valComparator = new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return (int)(o1.val - o2.val);
}
};
}
本次题目是“合并K个排序链表”,其实我们可以从题目合并两个有序链表中获得灵感,将K个链表两两合并(merge lists onr by one),得到最终结果。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
private ListNode mergeTwoLists(ListNode l1, ListNode l2){
if(l1 == null) return l2;
if(l2 == null) return l1;
if(l1.val < l2.val){
l1.next = mergeTwoLists(l1.next,l2);
return l1;
}else{
l2.next = mergeTwoLists(l1,l2.next);
return l2;
}
}
public ListNode mergeKLists(ListNode[] lists) {
ListNode head = new ListNode(0);
ListNode point = head;
for(ListNode node:lists){
point.next = mergeTwoLists(point.next,node);
}
return head.next;
}
}
将K个链表分成两两一组,使用方法:合并两个有序链表,将其合并,再将结果两两分组,合并,直到得到最终结果。
class Solution {
private ListNode mergeTwoLists(ListNode l1, ListNode l2){
if(l1==null)return l2;
if(l2==null)return l1;
if(l1.val<l2.val){
l1.next=mergeTwoLists(l1.next, l2);
return l1;
}else{
l2.next=mergeTwoLists(l1, l2.next);
return l2;
}
}
public ListNode mergeKLists(ListNode[] lists) {
if(lists==null||lists.length==0)return null;
int length = lists.length;
int interval = 1;
while (interval < length) {
for (int i = 0; i < length - interval; i += interval * 2) {
lists[i] = mergeTwoLists(lists[i], lists[i + interval]);
}
interval *= 2;
}
return lists[0];
}
}
C++:
方法一:
struct ListNode
{
int val;
ListNode* next;
ListNode(int x):val(x),next(NULL) {}
};
class Solution
{
public:
ListNode* mergeKLists(vector<ListNode*>&lists)
{
ListNode* result = new ListNode(0);
ListNode* point = result;
list<int> l = list<int>();
for(int i=0; i<lists.size(); i++)
{
while(lists[i])
{
l.push_back(lists[i]->val);
lists[i]=lists[i]->next;
}
}
l.sort();
for(list<int>::iterator it = l.begin(); it!=l.end(); it++)
{
point->next=new ListNode(*it);
point=point->next;
}
return result->next;
}
};
方法二:
ListNode* mergeKLists(vector<ListNode*>&lists)
{
ListNode* result = new ListNode(0);
ListNode* point = result;
while(true)
{
int min_val = INT_MAX;
int position = -1;
for(int i=0;i<lists.size();i++)
{
if(lists[i]!=NULL)
{
if(lists[i]->val<min_val)
{
min_val = lists[i]->val;
position = i;
}
}
}
if(min_val==INT_MAX)
break;
point->next = new ListNode(min_val);
point = point->next;
lists[position] = lists[position]->next;
}
return result->next;
}
class myCompare
{
public:
bool operator()(ListNode* node_1,ListNode* node_2)const
{
return node_1->val>node_2->val;
}
};
class Solution
{
public:
ListNode* mergeKLists(vector<ListNode*>&lists)
{
ListNode* head = new ListNode(0);
ListNode* point = head;
priority_queue<ListNode*,vector<ListNode*>,myCompare>q;
for(int i=0;i<lists.size();i++)
{
if(lists[i]!=NULL)
q.push(lists[i]);
}
while(!q.empty())
{
ListNode* current_node=q.top();
q.pop();
point->next=new ListNode(current_node->val);
point=point->next;
current_node=current_node->next;
if(current_node!=NULL)
q.push(current_node);
}
return head->next;
}
};
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
{
if(l1==NULL)return l2;
if(l2==NULL)return l1;
if(l1->val<l2->val)
{
l1->next=mergeTwoLists(l1->next,l2);
return l1;
}
else
{
l2->next=mergeTwoLists(l1,l2->next);
return l2;
}
}
ListNode* mergeKLists(vector<ListNode*>&lists)
{
ListNode* head = new ListNode(0);
ListNode* point = head;
for(int i=0; i<lists.size(); i++)
point->next=mergeTwoLists(point->next,lists[i]);
return head->next;
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
{
if(l1==NULL)return l2;
if(l2==NULL)return l1;
if(l1->val<l2->val)
{
l1->next=mergeTwoLists(l1->next,l2);
return l1;
}
else
{
l2->next=mergeTwoLists(l1,l2->next);
return l2;
}
}
ListNode* mergeKLists(vector<ListNode*>&lists)
{
if(lists.size()==0)return NULL;
int length=lists.size();
int interval=1;
while(interval<length)
{
for(int i=0; i<length-interval; i+=interval*2)
{
lists[i]=mergeTwoLists(lists[i],lists[i+interval]);
}
interval*=2;
}
return lists[0];
}