23. 合并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 _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= 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

 

你可能感兴趣的:(LeetCode)