楼主: Myron2017
跳转到指定楼层
上一主题 下一主题
收起左侧

刷题记录帖子

🔗
 楼主| Myron2017 2026-2-11 12:29:54 | 只看该作者
全局:
LC. 2460. Apply Operations to an Array
  1. class Solution:
  2.     def applyOperations(self, nums: List[int]) -> List[int]:
  3.         # do operations
  4.         for i in range(0, len(nums)-1):
  5.             if nums[i] == nums[i+1]:
  6.                 nums[i] *= 2
  7.                 nums[i+1] = 0
  8.         # moving zero to the end
  9.         slow = 0
  10.         for fast in range(len(nums)):
  11.             if nums[fast] != 0:
  12.                 if slow != fast:
  13.                     nums[slow], nums[fast] = nums[fast], nums[slow]
  14.                 slow += 1
  15.         return nums
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-12 10:51:59 | 只看该作者
全局:
LC  24. Swap Nodes in Pairs

这道题要干什么?→ 两两交换相邻节点
核心技巧是什么?→ dummy 节点 + 三步指针交换
循环条件是什么?→ prev.next and prev.next.next
指针怎么移动?→ prev = first
返回什么?→ dummy.next
  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. #     def __init__(self, val=0, next=None):
  4. #         self.val = val
  5. #         self.next = next

  6. class Solution:
  7.     def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
  8.         # 边界情况:空链表或只有一个节点,无需交换
  9.         if not head or not head.next:
  10.             return head
  11.         
  12.         # 创建虚拟头节点,简化头节点的处理
  13.         dummy = ListNode(0)
  14.         dummy.next = head
  15.         
  16.         # prev 始终指向当前需要交换的一对节点的前一个节点
  17.         prev = dummy
  18.         
  19.         # 循环条件:确保存在完整的一对节点(prev.next 和 prev.next.next)
  20.         while prev.next and prev.next.next:
  21.             # 标识当前要交换的两个节点
  22.             first = prev.next           # 第一个节点
  23.             second = prev.next.next     # 第二个节点
  24.             
  25.             # 执行三步指针交换
  26.             # 步骤1:first 跳过 second,指向 second 后面的节点
  27.             first.next = second.next
  28.             # 步骤2:second 指向 first,完成反转
  29.             second.next = first
  30.             # 步骤3:prev 指向 second,使 second 成为这对节点的新头
  31.             prev.next = second
  32.             
  33.             # 移动 prev 到下一对节点的前面(即当前的 first)
  34.             # 因为 first 现在在 second 后面了
  35.             prev = first
  36.         
  37.         # 返回新的头节点
  38.         return dummy.next
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-13 09:27:39 | 只看该作者
全局:
LC 547. Number of Provinces
  1. from collections import deque

  2. class Solution:
  3.     def findCircleNum(self, isConnected: List[List[int]]) -> int:
  4.         n = len(isConnected)
  5.         visited = [False] * n
  6.         count = 0

  7.         for i in range(n):
  8.             if not visited[i]:
  9.                 queue = deque([i])  # ⭐ 使用 deque
  10.                 visited[i] = True
  11.                
  12.                 while queue:
  13.                     curr = queue.popleft()  # ⭐ O(1) 出队
  14.                     for j in range(n):
  15.                         if isConnected[curr][j] == 1 and not visited[j]:
  16.                             queue.append(j)
  17.                             visited[j] = True
  18.                
  19.                 count += 1

  20.         return count
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-13 10:00:40 | 只看该作者
全局:
LC. 904. Fruit Into Baskets

💡 关键点总结

题目转化能力:水果篮 → 最多 2 种不同元素的最长子数组
滑动窗口:双指针 + 哈希表维护窗口状态
窗口收缩:当条件不满足时,移动 left 直到满足
时间优化:每个元素最多进出窗口各一次,O(n)
算法步骤
右指针不断右移,扩大窗口
用哈希表记录窗口内每种水果的数量
当窗口内水果种类 > 2 时:
左指针右移,缩小窗口
直到窗口内只有 2 种水果
记录最大窗口长度
  1. class Solution:
  2.     def totalFruit(self, fruits: List[int]) -> int:
  3.         from collections import defaultdict
  4.         
  5.         # 记录窗口内每种水果的数量
  6.         basket = defaultdict(int)
  7.         left = 0
  8.         max_fruits = 0
  9.         
  10.         for right in range(len(fruits)):
  11.             # 右指针的水果加入窗口
  12.             basket[fruits[right]] += 1
  13.             
  14.             # 当窗口内水果种类 > 2 时,收缩窗口
  15.             while len(basket) > 2:
  16.                 basket[fruits[left]] -= 1
  17.                 # 如果某种水果数量变为 0,移除这个键
  18.                 if basket[fruits[left]] == 0:
  19.                     del basket[fruits[left]]
  20.                 left += 1
  21.             
  22.             # 更新最大值
  23.             max_fruits = max(max_fruits, right - left + 1)
  24.         
  25.         return max_fruits
复制代码
回复

使用道具 举报

全局:
支持一下楼主。看到你2020年就开始刷了。
现在AI大行其道,其实这挺影响我刷题的热情的[捂脸]
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-13 22:52:44 | 只看该作者
全局:
夏日柠檬红茶 发表于 2026-2-12 21:35
支持一下楼主。看到你2020年就开始刷了。
现在AI大行其道,其实这挺影响我刷题的热情的[捂脸]

我也不喜欢刷题,但是没办法,面试还没改革,那就得继续刷。加油!
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-14 11:54:41 | 只看该作者
全局:
LC 799. Champagne Tower

一、题目本质

这是一个:

✅ 流量扩散模型
✅ 二维 DP 模拟
✅ 局部溢出向下分配问题

核心思想:

每个杯子容量 = 1

只向下传递“溢出部分”

二、核心建模思想
1️⃣ 状态定义
dp[r][c] = 流到 (r,c) 的总量


⚠️ 注意:

我们存的是“流入总量”,
而不是“当前杯子里的剩余容量”。

2️⃣ 状态转移公式

当:

dp[r][c] > 1


溢出:

overflow = dp[r][c] - 1


向下流:

dp[r+1][c]     += overflow / 2
dp[r+1][c+1]   += overflow / 2

3️⃣ 最终答案
min(1, dp[query_row][query_glass])


因为杯子最多只能装 1。


这题的结构:

(r,c) → (r+1,c) 和 (r+1,c+1)


十、记忆口诀

只传溢出,不管满杯
自顶向下,逐层推进
最后截断,min(1, ans)
  1. class Solution:
  2.     def champagneTower(self, poured: int, query_row: int, query_glass: int) -> float:
  3.         # dp[r][c] 表示流到第 r 行第 c 个杯子的香槟总量(不是最终容量)
  4.         # 只需要计算到 query_row 行即可
  5.         dp = [[0.0] * (r + 1) for r in range(query_row + 1)]

  6.         # 初始时,所有香槟都倒入顶部杯子
  7.         dp[0][0] = poured

  8.         # 从第 0 行开始逐层向下模拟流动
  9.         for r in range(query_row):
  10.             for c in range(r + 1):

  11.                 # 如果当前杯子超过容量 1,才会发生溢出
  12.                 if dp[r][c] > 1:

  13.                     # 计算溢出量(超过 1 的部分)
  14.                     overflow = dp[r][c] - 1

  15.                     # 溢出部分平均分给下一层左右两个杯子
  16.                     dp[r + 1][c]     += overflow / 2.0
  17.                     dp[r + 1][c + 1] += overflow / 2.0

  18.                     # 注意:
  19.                     # 不需要把 dp[r][c] 截断为 1
  20.                     # 因为后续不会再用它继续传递(只用 overflow)

  21.         # 杯子最大容量为 1,因此最终结果取 min(1, 实际流入量)
  22.         return min(1.0, dp[query_row][query_glass])
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-15 07:05:05 | 只看该作者
全局:
LC. 66. Plus One

Easy 题,但是需要注意,进位 carry 在最后的时候需要 加上一位。


  1. class Solution:
  2.     def plusOne(self, digits: List[int]) -> List[int]:
  3.         carry = 1  # 因为我们要 +1
  4.         
  5.         # 从最后一位往前处理
  6.         for i in range(len(digits) - 1, -1, -1):
  7.             
  8.             digit_sum = digits[i] + carry
  9.             
  10.             digits[i] = digit_sum % 10
  11.             carry = digit_sum // 10
  12.             
  13.             # 如果已经没有进位,可以提前结束
  14.             if carry == 0:
  15.                 return digits
  16.         
  17.         # 如果循环结束还有进位,说明最高位也进位了
  18.         if carry:
  19.             return [1] + digits
  20.         
  21.         return digits

复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-15 10:22:29 来自APP | 只看该作者
全局:
LC 1411. Number of Ways to Paint N × 3 Grid


一、这题本质是什么?
这是:
固定宽度(3列)的网格染色 DP
行与行之间做状态转移
关键特点:
  • 行数 n 很大(5000)
  • 列数固定(3)
  • 每个格子 3 种颜色
  • 上下左右不能相同


二、第一步:降维思想(最重要)
因为列数只有 3,
👉 每一行的合法状态是有限的(12种)
所以可以:
把二维问题压缩成“按行”的一维 DP

三、第二步:状态压缩
一行合法情况共 12 种,但可以分类:
🟢 类型1:ABA(两种颜色)
a b a
数量:
3 × 2 = 6


🔵 类型2:ABC(三种颜色)
a b c
数量:
3 × 2 × 1 = 6


所以:总 12 = 6 + 6







所以

            new_two = (three * 2 + two * 3) % MOD
            new_three = (three * 2 + two * 2) % MOD

这是系数转移矩阵


代码就比较简单了,


class Solution:
    def numOfWays(self, n: int) -> int:
        MOD = 10**9 + 7
        
        # 初始状态:第一行
        # three: 三色模式数量,two: 双色模式数量
        three = 6  # ABC, ACB, BAC, BCA, CAB, CBA
        two = 6    # ABA, BAB, ACA, CAC, BCB, CBC
        
        # 从第 2 行开始推导
        for i in range(2, n + 1):
            # 计算新的三色和双色数量
            new_two = (three * 2 + two * 3) % MOD
            new_three = (three * 2 + two * 2) % MOD
            
            
            # 更新状态
            three = new_three
            two = new_two
        
        # 答案是两种模式的总和
        return (three + two) % MOD

回复

使用道具 举报

🔗
 楼主| Myron2017 2026-2-15 23:33:05 | 只看该作者
全局:
LC. 67. Add Binary
  1. class Solution:
  2.     def addBinary(self, a: str, b: str) -> str:
  3.      if a == "0":
  4.           return b
  5.       if b == "0":
  6.           return a
  7.       return bin(int(a,base=2) + int(b,base=2))[2:]
  8.                
  9.         
复制代码
  1. class Solution:
  2.     def addBinary(self, a: str, b: str) -> str:
  3.         n = max(len(a), len(b))
  4.         a = a.zfill(n)
  5.         b = b.zfill(n)

  6.         carry = 0
  7.         ans = []

  8.         for i in range(n-1, -1, -1):
  9.             if a[i] == "1":
  10.                 carry += 1
  11.             if b[i] == "1":
  12.                 carry += 1

  13.             if carry % 2 == 1:
  14.                 ans.append("1")
  15.             else:
  16.                 ans.append("0")
  17.             
  18.             carry = carry // 2
  19.         if carry == 1:
  20.             ans.append("1")
  21.         ans.reverse()

  22.         return "".join(ans)
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表