【如果笔记对你有帮助,欢迎关注&点赞&收藏,收到正反馈会加快更新!谢谢支持!】
ps:笔记和代码按本人理解整理,重思路
往期笔记:
LeetCode HOT100刷题笔记(一):哈希表, 双指针_leetcode刷题笔记模板-CSDN博客
LeetCode HOT100刷题笔记(二):滑动窗口,数组_leetcode hot100里有哪些是滑动窗口-CSDN博客
LeetCode HOT100刷题笔记(三):子串,矩阵_leecode热门100题-CSDN博客
题目22: 相交链表
- 题意:找到两个单链表相交的起始节点(如存在)
- 关键:两个指针分别从两个头出发,让他们走同样长度的路,可以相聚在相交点
- 代码:
class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]: p, q = headA, headB while p is not q: p = p.next if p else headB q = q.next if q else headA return p
题目23: 反转链表
- 拆解:
- 代码:
class Solution: def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: pre, cur = None, head while cur: tmp = cur.next cur.next = pre pre = cur cur = tmp return pre
题目24: 回文链表
- 题意:判断链表是否为回文链表
- 关键:快慢指针(找到链表中间节点) + 反转链表(反转后半段链表)
- 拆解:
step1: 找到链表中间节点【快慢指针】 step2:反转后半段链表【反转链表】 step3: 比对前后两段链表 「代码逻辑」 【step 1】 快(fast)慢(slow)指针初始化在head while fast和fast.next都存在: slow 走一步 fast 走两步 最后slow会指在链表中间 【step2】 同23.反转链表 【step3】 比对两段链表
- 代码:
class Solution: def isPalindrome(self, head: Optional[ListNode]) -> bool: mid = self.findMid(head) head2 = self.reverseList(mid) while head2: if head.val != head2.val: return False head = head.next head2 = head2.next return True def findMid(self, head): slow = head fast = head while fast and fast.next: slow = slow.next fast = fast.next.next return slow def reverseList(self, head): pre = None cur = head while cur: nxt = cur.next cur.next = pre pre = cur cur = nxt return pre
题目25: 环形链表
- 题意:判断链表是否存在环
- 关键:只要快指针追上慢指针,则一定存在环
- 代码:
class Solution: def hasCycle(self, head: Optional[ListNode]) -> bool: if not head: return False fast = head slow = head while fast and fast.next: fast = fast.next.next slow = slow.next if fast == slow: return True return False
题目26: 环形链表 II
- 题意:判断是否有环 + 找入口(有环)
- 关键:找到相遇点
-
拆解:
「代码逻辑」 while 快指针还能继续走: - 快指针走两步 - 慢指针走一步 if 两指针相遇: # 此时两个指针作用改变 - 一个指针去head - 两个指针同时走,直到相遇,返回指针位置节点
-
代码:
class Solution: def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: fast = head slow = head while fast and fast.next: fast = fast.next.next slow = slow.next if fast == slow: # 这时候改变slow和fast指针的作用(变成指针1和指针2) # 指针1:slow;指针2:fast (两个指针每次都走一步) fast = head while slow != fast: fast = fast.next slow = slow.next return fast return None
题目27: 合并两个有序链表
- 题意:将两个升序链表合并为一个新的 升序 链表
- 拆解:
「代码逻辑」 新链表:dummy_head(cur) -> … while 两个链表都有剩余: - list1和list2谁(的头节点)小谁(的头节点)加到新链表 - 指针移动 拼接剩余链表(如存在)
- 代码:
class Solution: def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: dummy_head = ListNode() cur = dummy_head while list1 and list2: if list1.val <= list2.val: cur.next = list1 list1 = list1.next else: cur.next = list2 list2 = list2.next cur = cur.next cur.next = list1 or list2 return dummy_head.next
题目28: 两数相加
- 题意:两个链表相加合成新链表(从头节点开始,注意进位)
- 拆解:
「代码逻辑」 新链表:dummy_head(cur) -> … val:记录进位 while 有剩余链表 or 有进位: val(之前的进位) += 两个链表(如存在)的值 新链表 -> 新节点(值为val%10) val更新进位(val//10)
- 代码:
class Solution: def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]: dummy_head = ListNode() cur = dummy_head val = 0 while l1 or l2 or val: if l1: val += l1.val l1 = l1.next if l2: val += l2.val l2 = l2.next cur.next = ListNode(val=val%10) val = val // 10 cur = cur.next return dummy_head.next
题目29: 删除链表的倒数第 N 个结点
19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)
- 题意:
- 拆解:
- 代码:
class Solution: def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]: dummy_head = ListNode(next=head) left = right = dummy_head for _ in range(n): right = right.next while right.next: left = left.next right = right.next left.next = left.next.next return dummy_head.next