合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。
示例:
輸入:
[ 1->4->5,
1->3->4,
2->6
]輸出: 1->1->2->3->4->4->5->6
#偷懶直接複製了以前的堆的** 所有看上去長了點
class priorityqueue:
# priority是設定優先順序 true為大根堆 false為小根堆
#modify為false的話 就僅僅是拷貝了arr陣列 但是不會修改原來陣列的值
#arr表示可以傳入乙個 將裡面的值直接變成優先順序佇列
def __init__(self,priority=true,modify=false,arr=):
#self._arr.clear()
self._arr=
self.priority=priority#設定他的優先順序 true為大根堆 false為小根堆
if not modify:#modify為false的話 就僅僅是拷貝了arr陣列 但是不會修改原來陣列的值
for i in arr:
# print(i,'i')
else:
self._arr=arr
self._index=len(self._arr)-1#指向最後乙個元素
#print('len(self._arr)=', len(self._arr))
self.firstbuildheap()
#index代表要進行向下調整的結點
def isempty(self):
if len(self._arr)>0:
return false
return true
def buildheap(self,index,_arr):
if self._index==-1: #如果堆裡沒有原始 則返回
return
t = _arr[index]
temp = _arr[index].key # temp代表index下標的值
k = (index * 2) + 1 # k代表index的左子樹
lenth = len(_arr) - 1
#print(lenth,'len')
if self.priority:
while k<=lenth:
#print('b')
if k_arr[k + 1].key: # 如果k的左子樹小於length(也就是k還有右子樹)並且它的右子樹大於它
k += 1 # k++ k指向了右子樹
if _arr[k].key > temp: # 如果temp大於當前子樹的最大值(無論左子樹還是右子樹都大於,因為上個判斷已經判斷了左右子樹大小)
break # 直接返回
_arr[index] = _arr[k] # 如果temp不大於左子樹或者右子樹的值 將k結點(index子樹)的值賦給inedx結點值
index = k # 要調整的結點變為k 因為index結點已經判斷完了
k = (k * 2) + 1 # k變成index的左子樹
_arr[index] = t
pass
def firstbuildheap(self):
index=(len(self._arr)//2)-1
while index>=0:
self.buildheap(index,self._arr)
index-=1
def get_arr(self):
return self._arr
def getmaxpriority(self):
if self._index == -1: #如果_index為-1 則堆為空
return
self.__swap(0,self._index,self._arr)#不然交換堆頂元素和最後的元素
maxpriorityvalue=self._arr[self._index] #交換後取得最後乙個元素
self.__remove() #刪除最後乙個元素
return maxpriorityvalue #返回最大值
def __remove(self):
if self._index==-1: #如果_index為-1 則堆為空
return
self._arr.pop() #刪除最後乙個元素
self._index-=1
self.buildheap(0,self._arr)#因為目前堆頂元素是未知的,所以要進行一次調整
return
def insert(self,key,value):
n=node(key,value)
self._index += 1 # index++ index代表了value的下標
index = self._index
if index % 2 == 0:
parent = index // 2 - 1
else:
parent = index // 2 # 獲取index的父節點
temp = self._arr[index].key # 獲取當前帶插入元素的key值
t=self._arr[index] # 獲取當前帶插入元素
if self.priority:
#上濾while parent>=0: #如果沒超過根節點 也就是index的父節點最大只能為0號下標
if temp= 0: # 如果沒超過根節點 也就是index的父節點最大只能為0號下標
if temp > self._arr[parent].key : # 如果下標index的值也就是value小於它的父節點,沒破壞堆序性
break
# print(index,parent)
self._arr[index] = self._arr[parent] # 不然的話將它的父節點的值賦給index
index = parent # index的父節點成為新的待調整結點
if index % 2 == 0:
parent = index // 2 - 1
else:
parent = index // 2 # 取得新index的父節點
self._arr[index] = t # 迴圈結束後將temp也就是value的值給最後停下來的index
return
def __swap(self,i,j,arr):
k=arr[i]
arr[i]=arr[j]
arr[j]=k
class solution(object):
def mergeklists(self, lists):
""":type lists: list[listnode]
:rtype: listnode
"""l=none
node=listnode(0)
pq = priorityqueue(priority=false)
for i in range(len(lists)):
while true:
if not lists[i]:
break
pq.insert(lists[i].val,lists[i])
lists[i]=lists[i].next
#使用乙個小根堆
while not pq.isempty():
temp=pq.getmaxpriority()
node.next=temp.value
if not l:
l=node.next
node=node.next
node.next=none
return l
23 合併K個排序鍊錶
合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。採用分治法的思想,將 k 個排序鍊錶先合併為 k 2 個鍊錶。依次迴圈,直至合併為1個鍊錶為止。注意 從 k 到 k 2 時,如何定義索引,將每兩個鍊錶合併,而且必須符合奇數 偶數個鍊錶的情況。解決辦法 k n 1 2 list...
23 合併K個排序鍊錶
合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。示例 輸入 1 4 5,1 3 4,2 6 輸出 1 1 2 3 4 4 5 6 暴力法 將所有的節點放在乙個陣列中,然後對陣列排序,最後遍歷陣列,組建新的鍊錶。definition for singly linked list...
23 合併K個排序鍊錶
題目.很有意思 第一想法就是使用最小堆或者比較樹,這個方法當然是可以的,但是用go語言難寫,尤其是比較樹。採用歸併排序的思想倒是很快,每次比較都需要比較o n 次,一共log2k次 package main import fmt type listnode struct func printlist...