問題:在o(n lgk) 時間內合併k個有序鍊錶, 這裡n指的是k個鍊錶中所有的元素個數。
這題的思路如下:
1 ) 在每乙個鍊錶中取出第乙個值,然後把它們放在乙個大小為k的陣列裡,然後把這個陣列當成heap,然後把該堆建成最小堆。o(k)
2 )取出堆中的最小值(也是陣列的第乙個值),然後把該最小值所處的鍊錶的下乙個值放在陣列的第乙個位置。如果鍊錶中有乙個已經為空(元素已經都被取出),則改變heap的大小。然後,執行min-heapify操作,o(lg k).
3 ) 不斷的重複步驟二,直到所有的鍊錶都為空。
class listnode
}public class solution
} public listnode mergeklists(arraylistlists)
}listnode head = null;
listnode current = null;
if (heap.size() == 0) return null;
minheapify(heap);
while (heap.size() != 0) else
if (current.next != null) else
}return head;
} public void heapify(arraylistheap, int index)
if(right < heap.size() && heap.get(right).val < heap.get(position).val)
if (position != index)
}public void minheapify(arraylistheap)
}}
合併兩個有序鍊錶:
一般有兩種方法:遞迴和非遞迴。
尤其注意兩個鍊錶都為空,和其中乙個為空時的情況。只需要o(1)的空間。時間複雜度為o(max(len1, len2))。
1、遞迴:設兩個鍊錶的頭結點分別是head1,和head2。如果head1為空,直接返回head2;同理如果head2為空,直接返回head1。否則,如果head1鍊錶的第乙個資料小於head2鍊錶的第乙個資料,那麼直接繼續遞迴
head1->next和head2這兩個鍊錶,並把返回值賦給head1->next。
node * listmerge(node *head1, node * head2)
else
node->next = listmerge(head1, head2);
return node;
}
2:非遞迴的:分別用指標head1,head2來遍歷兩個鍊錶,如果當前head1指向的資料小於head2指向的資料,則將head1指向的結點歸入合併後的鍊錶中,否則,將head2指向的結點歸入合併後的鍊錶中。如果有乙個鍊錶遍歷結束,則把未結束的鍊錶連線到合併後的鍊錶尾部。// 合併兩個有序鍊錶
listnode * mergesortedlist(listnode * phead1, listnode * phead2)
else
listnode * ptemp = pheadmerged;
while(phead1 != null && phead2 != null)
else
}if(phead1 != null)
ptemp->m_pnext = phead1;
else if(phead2 != null)
ptemp->m_pnext = phead2;
return pheadmerged;
}
合併K個有序鍊錶
public class 023 mergeklists 堆中結點類 author luzhen work pc private static class node implements comparable override public int compareto node o 將k個有序鍊錶歸...
合併k個有序鍊錶
這是leetcode上面的一道程式設計題,題目如下 合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。示例輸入 1 4 5,1 3 4,2 6 輸出 1 1 2 3 4 4 5 6 利用遞迴分治的思想將k個有序鍊錶的合併問題,分解成多個合併兩個有序鍊錶的問題。比如示例中我們將三...
合併k個有序鍊錶
題幹 合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。示例 輸入 1 4 5,1 3 4,2 6 輸出 1 1 2 3 4 4 5 6 此題為leetcode中23題。由於此前有合併兩個有序鍊錶的經驗,開始看到這個題,很自然就想到了,每次在k個鍊錶中選取乙個最小的節點鏈結到結...