LeetCode HOT100刷题笔记(四):链表

【如果笔记对你有帮助,欢迎关注&点赞&收藏,收到正反馈会加快更新!谢谢支持!】

ps:笔记和代码按本人理解整理,重思路

往期笔记:

LeetCode HOT100刷题笔记(一):哈希表, 双指针_leetcode刷题笔记模板-CSDN博客

LeetCode HOT100刷题笔记(二):滑动窗口,数组_leetcode hot100里有哪些是滑动窗口-CSDN博客

LeetCode HOT100刷题笔记(三):子串,矩阵_leecode热门100题-CSDN博客

题目22: 相交链表

160. 相交链表 - 力扣(LeetCode)

  • 题意:找到两个单链表相交的起始节点(如存在)
  • 关键:两个指针分别从两个头出发,让他们走同样长度的路,可以相聚在相交点
  • 代码:
    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: 反转链表

160. 相交链表 - 力扣(LeetCode)

  • 拆解:
  • 代码:
    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: 回文链表

234. 回文链表 - 力扣(LeetCode)

  • 题意:判断链表是否为回文链表
  • 关键:快慢指针(找到链表中间节点) + 反转链表(反转后半段链表)
  • 拆解:
    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: 环形链表

141. 环形链表 - 力扣(LeetCode)

  • 题意:判断链表是否存在环
  • 关键:只要快指针追上慢指针,则一定存在环
  • 代码:
     
    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

142. 环形链表 II - 力扣(LeetCode)

  • 题意:判断是否有环 + 找入口(有环)
  • 关键:找到相遇点
  • 拆解:

    「代码逻辑」
    
    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: 合并两个有序链表

21. 合并两个有序链表 - 力扣(LeetCode)

  • 题意:将两个升序链表合并为一个新的 升序 链表
  • 拆解:
    「代码逻辑」
    
    新链表: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: 两数相加

2. 两数相加 - 力扣(LeetCode)

  • 题意:两个链表相加合成新链表(从头节点开始,注意进位)
  • 拆解:
    「代码逻辑」
    
    新链表: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值