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

刷题记录帖子

🔗
 楼主| Myron2017 2026-3-15 00:10:59 来自APP | 只看该作者
全局:
LC. 3823. Reverse Letters Then Special Characters in a String

优化就是 stack 如何反转,其实直接 pop 就行,不需要 revese + pop(0)

在 Python 中,list.pop(0) 会导致后续所有元素向前移动,这是一个 O(N) 的操作。如果字符串很长,整个循环就会变成 O(N^2)。
  1. class Solution:
  2.     def reverseByType(self, s: str) -> str:
  3.         letters = []
  4.         special = []

  5.         for ch in s:
  6.             if ch.isalpha():
  7.                 letters.append(ch)
  8.             else:
  9.                 special.append(ch)
  10.         #letters.reverse()
  11.         #special.reverse()
  12.         ans = []

  13.         for ch in s:
  14.             if ch.isalpha():
  15.                 ans.append(letters.pop())
  16.             else:
  17.                 ans.append(special.pop())
  18.         
  19.         return "".join(ans)
复制代码

补充内容 (2026-03-15 00:15 +08:00):
我们依然保持思路的清晰性,但通过从后弹出(
  1. pop()
复制代码
)来保证 $O(1)$ 的处理效率。
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-15 00:17:33 | 只看该作者
全局:
LC. 3813. Vowel-Consonant Score


一次遍历:只需要扫描一遍字符串 s,时间复杂度 $O(N)$。可读性高:逻辑分层清晰——先判断是不是字母,再判断是哪种字母。健壮性:ch.isalpha() 自动过滤了数字、空格和特殊符号,不管题目增加多少种非字母字符,这段逻辑依然稳健。
  1. class Solution:
  2.     def vowelConsonantScore(self, s: str) -> int:
  3.         vowels_set = {'a', 'e', 'i', 'o', 'u'}
  4.         v = 0
  5.         c = 0
  6.         
  7.         for ch in s:
  8.             # 只处理英文字母
  9.             if ch.isalpha():
  10.                 if ch in vowels_set:
  11.                     v += 1
  12.                 else:
  13.                     c += 1
  14.         
  15.         # 按照题目要求的逻辑:c > 0 才计算,否则返回 0
  16.         return v // c if c > 0 else 0
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-15 10:37:11 来自APP | 只看该作者
全局:
LC 1622. Fancy Sequence







构造 费马小定理的证明,可以跳过,直接记忆上面的结论。

考察对“大数处理”的敏感度
在分布式系统或后端开发中,经常会遇到数值溢出的问题。
  • 为什么要
    1. modulo 10^9 + 7
    复制代码
    ?
  • 为什么不能直接
    1. val / mult
    复制代码
    ?
如果你直接用浮点数除法,在 $10^{18}$ 级别的运算中,精度丢失会让你求出来的结果差之毫厘、谬以千里。在模运算下使用逆元,是计算机处理大数除法时唯一保持 100% 精确的方法。








class Fancy:
    def __init__(self):
        self.nums = []
        self.add = 0
        self.mult = 1
        self.mod = 10**9 + 7

    def append(self, val: int) -> None:
        # 我们存入的是一个“抵消”了当前 add 和 mult 影响的原始值
        # 逆运算:(val - add) / mult
        # 在模运算下,除法变乘法逆元
        # 使用 pow(a, -1, mod) 是 Python 3.8+ 推荐的高效写法,内部实现是扩展欧几里得
        inv_mult = pow(self.mult, self.mod - 2, self.mod)
        self.nums.append(((val - self.add) * inv_mult) % self.mod)

    def addAll(self, inc: int) -> None:
        self.add = (self.add + inc) % self.mod

    def multAll(self, m: int) -> None:
        self.mult = (self.mult * m) % self.mod
        self.add = (self.add * m) % self.mod

    def getIndex(self, idx: int) -> int:
        if idx >= len(self.nums):
            return -1
        # 取出时,应用当前的全局变换公式
        return (self.nums[idx] * self.mult + self.add) % self.mod

回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-15 23:12:21 | 只看该作者
全局:
LC . 3870. Count Commas in Range

贡献法:不用去算每个区间到底有多少个数,而是算“第 1 个逗号”出现了多少次,“第 2 个逗号”出现了多少次。
  1. class Solution:
  2.     def countCommas(self, n: int) -> int:
  3.         total_commas = 0
  4.         # start 是每个阶段产生更多逗号的起始点
  5.         # 1,000 (1个), 1,000,000 (2个), 1,000,000,000 (3个)...
  6.         start = 1000
  7.         
  8.         while n >= start:
  9.             # 每一个大于等于 start 的数,都至少贡献了“一个额外的逗号”
  10.             # 比如 1,000,001 既大于 1,000,也大于 1,000,000
  11.             # 它在这两次判断中各贡献 1 个,加起来正好是 2 个逗号
  12.             total_commas += (n - start + 1)
  13.             start *= 1000
  14.             
  15.         return total_commas
复制代码
  1. class Solution:
  2.     def countCommas(self, n: int) -> int:
  3.         if n < 1000:
  4.             return 0
  5.         return n - 1000 + 1
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-15 23:33:20 | 只看该作者
全局:
LC 3866. First Unique Even Element

核心算法模型:两次遍历法
第一次遍历:用哈希表(可以用 dict 或 collections.Counter)统计所有数字出现的次数。

第二次遍历:按顺序检查原数组中的每个元素,看它是否满足“偶数”且“计数为 1”。第一个满足的直接返回。
  1. from collections import Counter

  2. class Solution:
  3.     def firstUniqueEven(self, nums: list[int]) -> int:
  4.         # 1. 统计频率
  5.         freq = Counter(nums)
  6.         
  7.         # 2. 直接遍历原数组 nums,保证“First”(索引最早)
  8.         for n in nums:
  9.             # 直接在字典里查频率,O(1) 速度极快
  10.             if n % 2 == 0 and freq[n] == 1:
  11.                 return n
  12.                
  13.         # 3. 遍历完没找到,说明不存在
  14.         return -1
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-15 23:42:53 | 只看该作者
全局:
LC. 3803. Count Residue Prefixes
  1. class Solution:
  2.     def residuePrefixes(self, s: str) -> int:
  3.         ans = 0
  4.         seen = set()
  5.         
  6.         for i, char in enumerate(s):
  7.             # 增量更新 set
  8.             seen.add(char)
  9.             
  10.             # 当前前缀的长度
  11.             length = i + 1
  12.             # 不同字符的个数
  13.             distinct_count = len(seen)
  14.             
  15.             # 核心判断逻辑
  16.             if distinct_count == length % 3:
  17.                 ans += 1
  18.                
  19.         return ans
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-15 23:54:57 | 只看该作者
全局:
LC. 3798. Largest Even Number
  1. class Solution:
  2.     def largestEven(self, s: str) -> str:
  3.         n = len(s)
  4.         r = n - 1

  5.         while r >= 0:
  6.             if s[r] == '1':
  7.                 r -= 1
  8.             else:
  9.                 break
  10.         if r < 0: return ""
  11.         else:
  12.             return s[:r+1]
  13.         
复制代码
更加 Python 的写法
  1. class Solution:
  2.     def largestEven(self, s: str) -> str:
  3.         # rstrip('1') 会移除字符串右侧所有的 '1'
  4.         # 剩下的字符串末尾一定是 '2'(或者是空串)
  5.         return s.rstrip('1')
复制代码
s.rstrip('1'):从右边开始删,直到遇到不是 '1' 的字符为止。

如果删完后剩下了东西,最后一个字肯定是 '2',满足偶数要求。

中间的 '1' 和 '2' 都会被保留,保证了长度最长,数值最大。
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-15 23:57:08 | 只看该作者
全局:
LC 3794. Reverse String Prefix

在 Python 切片 s[:n] 中,n 直接代表了你想取出的字符个数。
想取前 k 个,直接写 [:k];想取前 5 个,直接写 [:5]。
  1. class Solution:
  2.     def reversePrefix(self, s: str, k: int) -> str:
  3.         stack = []

  4.         for ch in s[:k]:
  5.             stack.append(ch)

  6.         ans = ""
  7.         for i in range(k):
  8.             ans += stack.pop()
  9.         
  10.         if k == len(s): return ans
  11.         else:
  12.             return ans + s[k:]
  13.         
复制代码
优化点 A:利用 Python 切片的翻转步长Python 的切片支持 [::-1],这可以直接翻转一个序列。优化点 B:减少字符串拼接在 Python 中,字符串是不可变的。频繁地 ans += stack.pop() 会创建很多临时字符串对象。虽然这题 $n=100$ 没影响,但如果是 $n=10^6$,代码会慢得离谱。
  1. class Solution:
  2.     def reversePrefix(self, s: str, k: int) -> str:
  3.         # s[:k][::-1] -> 取前 k 个并翻转
  4.         # s[k:]       -> 取剩下的部分
  5.         return s[:k][::-1] + s[k:]
复制代码
为什么这更好?

切片翻转 [::-1]:由 Python 底层 C 语言实现,速度极快。

语义清晰:一眼就能看出是在翻转前 k 位。

不用判断 if k == len(s):如果 k 等于长度,s[k:] 会自动返回空字符串 "",拼接起来完全没问题。
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-16 11:29:55 来自APP | 只看该作者
全局:
LC .3783. Mirror Distance of an Integer

Python 直接 num 反转

reversed_n = int(str(n)[::-1])
  1. class Solution:
  2.     def mirrorDistance(self, n: int) -> int:
  3.         # str(n)[::-1] 直接得到反转后的字符串
  4.         reversed_n = int(str(n)[::-1])
  5.         return abs(n - reversed_n)
复制代码

补充内容 (2026-03-16 11:36 +08:00):
class Solution:
    def mirrorDistance(self, n: int) -> int:
        original_n = n
        reversed_n = 0
        temp = n
        
        while temp > 0:
            # 每次取出最后一位,加到 reversed_n 的末尾
            reversed_n = reversed_n * 10 + (temp % 10)
            temp //= 10
            
        return abs(original_n - reversed_n)
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-3-16 11:39:38 | 只看该作者
全局:
LC. 3774. Absolute Difference Between Maximum and Minimum K Elements

A. 排序法 (你的解法)思路:排序后取两头。复杂度:时间 $O(n \log n)$,空间 $O(1)$ 或 $O(n)$(取决于排序实现)。适用场景:$n$ 较小,或者需要多次查询不同 $k$ 值。B. 堆 (Heap) 法思路:维护一个大小为 $k$ 的大顶堆找最小 $k$ 个数,一个小顶堆找最大 $k$ 个数。复杂度:时间 $O(n \log k)$。适用场景:$n$ 非常大(如几百万),而 $k$ 很小(如前 10 名)。C. 快速选择 (Quick Select)思路:类似快排的分治思想,可以在不完全排序的情况下找到第 $k$ 小的数。复杂度:平均时间 $O(n)$。适用场景:极致的性能追求。
  1. import heapq

  2. class Solution:
  3.     def absDifference(self, nums: List[int], k: int) -> int:
  4.         # 直接获取最大的 k 个数和最小的 k 个数
  5.         max_k = heapq.nlargest(k, nums)
  6.         min_k = heapq.nsmallest(k, nums)
  7.         
  8.         return sum(max_k) - sum(min_k)
复制代码
  1. class Solution:
  2.     def absDifference(self, nums: List[int], k: int) -> int:
  3.         nums.sort() # 1. 升序排序
  4.         # 2. 前 k 个是最小的,后 k 个是最大的
  5.         return abs(sum(nums[:k]) - sum(nums[len(nums) - k:]))
复制代码
回复

使用道具 举报

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

本版积分规则

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