【力扣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道题!知识能进脑子的感觉真爽啊!
相关推荐
诚丞成几秒前
滑动窗口篇——如行云流水般的高效解法与智能之道(1)
算法
手握风云-10 分钟前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
nuclear20111 小时前
使用Python 在Excel中创建和取消数据分组 - 详解
python·excel数据分组·创建excel分组·excel分类汇总·excel嵌套分组·excel大纲级别·取消excel分组
Lucky小小吴1 小时前
有关django、python版本、sqlite3版本冲突问题
python·django·sqlite
带多刺的玫瑰1 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔1 小时前
《线性代数的本质》
线性代数·算法·决策树
陪学2 小时前
百度遭初创企业指控抄袭,维权还是碰瓷?
人工智能·百度·面试·职场和发展·产品运营
美式小田2 小时前
单片机学习笔记 9. 8×8LED点阵屏
笔记·单片机·嵌入式硬件·学习
熬夜学编程的小王2 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
yigan_Eins2 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法