python做题日记(11)
第二十五题
第二十五题是k个一组翻转链表,意思是给定一个链表,将每k个结点化成一组,对它们进行翻转操作,在对每一组都进行翻转操作之后,将它们重新连接起来,返回这个新的链表。所以代码思路也很好想,首先需要对链表的结点数量进行检查,如果链表结点的数量不足k个即无法进行分组,也就直接返回原链表。如果检查之后可以进行分组,就对前k个结点使用头插法进行翻转操作,最后将翻转后的链表与原链表相连,重复以上操作就可以完成对k个一组链表的翻转。
class Solution:def reverseKGroup(self, head: ListNode, k: int) -> ListNode:dummy = ListNode(0)dummy.next = headpre = dummywhile True:tail = pre# 检查剩余节点是否够 k 个for i in range(k):tail = tail.nextif not tail:return dummy.nextnex = tail.next# 翻转 k 个节点prev, curr = tail.next, pre.nextfor i in range(k):tmp = curr.nextcurr.next = prevprev = currcurr = tmp# 连接翻转后的部分tmp = pre.nextpre.next = tailpre = tmp
在这里对头插法翻转链表的过程进行一些解释,一开始我在理解的时候产生了一些混乱。这里一共有两个指针,还有一个临时指针用于进行交换,整个翻转的过程用一个表格来进行展示应该会更加清晰。在最开始检查链表结点数量是否足够k个的时候,将tail指针已经向后移动了k步。
步骤 | curr | prev | tmp | 操作 | 结果链表(已翻转部分用粗体) |
---|---|---|---|---|---|
1 | 1 | 4 | 2 | 1.next=4 | 1→4 2→3→4→5 |
2 | 2 | 1 | 3 | 2.next=1 | 2→1→4 3→4→5 |
3 | 3 | 2 | 4 | 3.next=2 | 3→2→1→4 4→5 |
- prev 初始为 tail.next(即4),curr 初始为 pre.next(即1)
- 每次把 curr 插到 prev 前面,prev向前推进,curr向后推进
这里的curr指的是当前需要操作的结点,prev指的是已经翻转好后链表的头结点,temp是用来暂存当前要操作结点的下一结点以防断链。每次把当前结点插到已经翻转后的结点的最前面就是头插法的思想。
第二十六题
第二十六题是删除有序数组中的重复项,这题可以使用双指针即快慢指针,快指针用来遍历数组,当快指针的值与慢指针的值不相等时,移动慢指针,并将快指针的值赋予移动后慢指针所指位置。慢指针用来保存不重复的部分,最后需要返回不含重复项数组的长度,因此返回慢指针+1即为数组长度,故有如下代码:
class Solution:def removeDuplicates(self, nums: list[int]) -> int:if not nums:return 0slow = 0for fast in range(1, len(nums)):if nums[fast] != nums[slow]:slow += 1nums[slow] = nums[fast]return slow + 1