合并 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')
self._arr.append(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<lenth and _arr[k].key<_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 #如果循环结束,说明调整完毕,最后index的值是将是它的子树的值,需要修改为value也就是temp的值
else:
while k <= lenth:
#print('a')
if k <lenth and _arr[k].key > _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._arr.append(n) # 将新值插入到堆尾
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<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
else:#小根堆
# 上滤
while parent >= 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