2021-11-02 每日打卡:腾讯精选50题

2021-11-02 每日打卡:腾讯精选50题

写在前面

“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,遵循LeetBook 列表/腾讯的刷题顺序,所有代码已通过。每日3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。

23. 合并K个升序链表

在这里插入图片描述

  • 最小堆:可以仿“合并两个有序链表”的方法,使用K个指针,比较出最小的连接,这里使用堆结构来优化,堆中始终保持K个元素,每次取最小的即可,记录链表index,取走后添加一个新的
import heapq
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        minheap, head = [], ListNode(0)
        for index in range(len(lists)):
            if lists[index]:
                # python中自定义堆只有一种实现方式:类内运算符重载
                # 所以下面也是只能新建一个结点啦
                heapq.heappush(minheap, (lists[index].val,index))
                lists[index] = lists[index].next
        tmp = head
        while minheap:
            num, index = heapq.heappop(minheap)
            tmp.next = ListNode(num)
            if lists[index]: 
                heapq.heappush(minheap,(lists[index].val,index))
                lists[index]=lists[index].next
            tmp = tmp.next
        return head.next
  • 归并排序:其中两个链表合成是使用的递归方法(也可以使用迭代,详见上一篇文章),同时要注意到归并排序的过程是“调用自身mergesort两部分+合并”
class Solution:
    def mergesort(self, lists, l, r):
        if l==r: return lists[l]
        mid = (l+r)//2
        l1 = self.mergesort(lists, l, mid)
        l2 = self.mergesort(lists,mid+1, r)
        return self.merge2lst(l1,l2)

    def merge2lst(self,l1,l2):
        if not l1: return l2
        if not l2: return l1
        if l1.val<l2.val:
            l1.next = self.merge2lst(l1.next, l2)
            return l1
        else:
            l2.next = self.merge2lst(l1, l2.next)
            return l2

    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        if not lists: return
        lenth = len(lists)
        return self.mergesort(lists, 0, lenth-1)
        

61. 旋转链表

在这里插入图片描述

  • 非常典型的切片连接和快慢指针问题:
class Solution:
    def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        if not head: return
        cur,n = head,1
        while cur.next:
            cur = cur.next
            n += 1
        slow = fast = head
        # 也可以写作fast = fast.next if fast.next else head
        # 但遍历一遍链表统计个数总比循环n遍要快噢
        for _ in range(k%n):
            fast = fast.next
        # fast移动到最后一个结点,之所以不向后是为了接起来
        while fast.next:
            fast = fast.next
            slow = slow.next
        fast.next = head
        head = slow.next
        slow.next = None
        return head

141. 环形链表

在这里插入图片描述

  • 快慢指针(这才是真正的快慢指针,上面的题应该称为前后指针🤣):只要有环,一定能追上
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        fast = slow = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                return True
        return False
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值