【力扣hot100】刷题笔记Day9

前言

  • 阴天睡得还挺舒服,9点半才醒,用刷题开启美好新一天!

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

哈希表

```python
class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        seen = set()  # 哈希集合
        # seen = {}  # 哈希字典
        cur = head
        while cur:
            if cur in seen:  # 有重复的节点则有环
                return True
            seen.add(cur)  # 直接存节点
            # seen[cur] = True  # 将节点作为键,值设为True
            cur = cur.next
        return False
```

快慢指针

```python
class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        slow = fast = head  # 乌龟和兔子同时从起点出发
        while fast and fast.next:
            slow = slow.next  # 乌龟走一步
            fast = fast.next.next  # 兔子走两步
            if fast == slow:  # 兔子追上乌龟(套圈),说明有环
                return True
        return False  # 访问到了链表末尾,无环
```

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

快慢指针

```python
class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        fast = slow = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if slow == fast:  # 快慢指针相遇,s走了nb,f走了2nb
                fast = head  # 入口处需要a+nb,s已经走了nb
                while fast != slow:  # 同时走a就可到达入口
                    fast = fast.next
                    slow = slow.next
                return fast
        return None
```

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

迭代法

```python
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        prehead = ListNode(-1)
        precur = prehead
        while list1 and list2:
            if list1.val <= list2.val:  # 把较小值接到precur后面
                precur.next = list1
                list1 = list1.next
            else:
                precur.next = list2
                list2 = list2.next
            precur = precur.next  # 记得让precur前进
        # 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        precur.next = list1 if list1 else list2
        return prehead.next
```

递归法

```python
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        if list1 is None:
            return list2
        if list2 is None:
            return list1
        if list1.val < list2.val:
            list1.next = self.mergeTwoLists(list1.next, list2)
            return list1
        else:
            list2.next = self.mergeTwoLists(list2.next, list1)
            return list2
```

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

模拟------转数字

```python
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        # 链表转化为数字
        def getNum(head):
            num = 0
            flag = 1
            while head != None:
                num += head.val * flag
                head = head.next
                flag *= 10
            return num
        # 计算和    
        twoSum = getNum(l1) + getNum(l2)
        # 和为0直接返回0节点
        if twoSum == 0:
            return ListNode(0)
        # 循环生成新链表
        head = cur = ListNode(-1)
        while twoSum != 0:
            cur.next = ListNode(twoSum % 10)
            cur = cur.next
            twoSum //= 10  # 整除
        return head.next
```

模拟------进位

```python
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        # 创建一个结点值为 None 的头结点, dummy 和 p 指向头结点, dummy 用来最后返回, p 用来遍历
        dummy = p = ListNode(None)          
        s = 0               # 初始化进位 s 为 0
        while l1 or l2 or s:
            # 如果 l1 或 l2 存在, 则取l1的值 + l2的值 + s(s初始为0, 如果下面有进位1, 下次加上)
            s += (l1.val if l1 else 0) + (l2.val if l2 else 0)  
            p.next = ListNode(s % 10)       # p.next 指向新链表, 用来创建一个新的链表
            p = p.next                      # p 向后遍历
            s //= 10                        # 有进位情况则取模, eg. s = 18, 18 // 10 = 1
            l1 = l1.next if l1 else None    # 如果l1存在, 则向后遍历, 否则为 None
            l2 = l2.next if l2 else None    # 如果l2存在, 则向后遍历, 否则为 None
        return dummy.next   # 返回 dummy 的下一个节点, 因为 dummy 指向的是空的头结点, 下一个节点才是新建链表的后序节点
```

递归------进位

```python
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        def dfs(l, r, i):
            # 终止条件:都为空节点且进位为0
            if not l and not r and not i: return None
            s = (l.val if l else 0) + (r.val if r else 0) + i
            node = ListNode(s % 10)  # 当前节点
            node.next = dfs(l.next if l else None, r.next if r else None, s // 10) # 接上递归链表
            return node
        return dfs(l1, l2, 0)
```

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

双指针

```python
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        dummy = ListNode(0, head)  # 直接创建虚拟头节点
        fast = slow = dummy  # 双指针
        # 快指针先走
        while n != 0:
            fast = fast.next
            n -= 1
        # 双指针一起走直到fast到底
        while fast.next != None:
            fast = fast.next
            slow = slow.next
        # 删除节点
        slow.next = slow.next.next
        return dummy.next
```

24. 两两交换链表中的节点 - 力扣(LeetCode)

模拟 ​​​​​

```python
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        dummy = ListNode(0, head)
        cur = dummy
        while cur.next and cur.next.next:
            pre = cur
            cur = cur.next
            temp = cur.next.next
            pre.next = cur.next  # 步骤1
            pre.next.next = cur  # 步骤2
            cur.next = temp      # 步骤3
        return dummy.next
```

递归

```python
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 终止条件:如果剩0/1个节点,无法交换,直接返回
        if not head or not head.next:
            return head
        # 交换头两个结点
        newhead = head.next
        head.next = self.swapPairs(newhead.next)  # 接上后面交换好的结果
        newhead.next = head
        return newhead
```

后言

  • 明天估计是不开组会的,今天猛猛刷了6道题!知识能进脑子的感觉真爽啊!
相关推荐
A懿轩A43 分钟前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
古希腊掌管学习的神43 分钟前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵
云边有个稻草人1 小时前
【优选算法】—复写零(双指针算法)
笔记·算法·双指针算法
半盏茶香1 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
忘梓.2 小时前
解锁动态规划的奥秘:从零到精通的创新思维解析(3)
算法·动态规划
LucianaiB2 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
️南城丶北离2 小时前
[数据结构]图——C++描述
数据结构··最小生成树·最短路径·aov网络·aoe网络
✿ ༺ ོIT技术༻2 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
PieroPc4 小时前
Python 写的 智慧记 进销存 辅助 程序 导入导出 excel 可打印
开发语言·python·excel
tinker在coding4 小时前
Coding Caprice - Linked-List 1
算法·leetcode