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