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

刷题记录帖子

🔗
 楼主| Myron2017 2026-5-11 08:58:53 | 只看该作者
全局:
LC. 2553. Separate the Digits in an Array

我的解法
  1. class Solution:
  2.     def separateDigits(self, nums: List[int]) -> List[int]:
  3.         ans = []

  4.         for n in nums:
  5.             for ch in str(n):
  6.                 ans.append(int(ch))
  7.         return ans
  8.         
复制代码
高级的 列表推导 List Comprehension
  1. class Solution:
  2.     def separateDigits(self, nums: List[int]) -> List[int]:
  3.         # 嵌套循环的列表推导式
  4.         # 先遍历 nums 里的 n,再遍历 str(n) 里的 c
  5.         return [int(c) for n in nums for c in str(n)]
复制代码
如果不能用 string,那就是 % 10 和 // 10 了
  1. class Solution:
  2.     def separateDigits(self, nums: List[int]) -> List[int]:
  3.         ans = []
  4.         # 为了保持顺序,我们需要处理每一个数字
  5.         for n in nums:
  6.             # 临时存放当前数字拆分出来的位
  7.             temp = []
  8.             while n > 0:
  9.                 temp.append(n % 10)
  10.                 n //= 10
  11.             # 因为取模是逆序的,所以要反转回来再加入结果
  12.             ans.extend(temp[::-1])
  13.         return ans
复制代码
需要注意,要反转输出答案,取模是逆序的
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-12 11:13:38 | 只看该作者
全局:
LC. 1665. Minimum Initial Energy to Finish Tasks

You are given an array tasks where tasks[i] = [actuali, minimumi]:

actuali is the actual amount of energy you spend to finish the ith task.
minimumi is the minimum amount of energy you require to begin the ith task.
For example, if the task is [10, 12] and your current energy is 11, you cannot start this task. However, if your current energy is 13, you can complete this task, and your energy will be 3 after finishing it.

You can finish the tasks in any order you like.

Return the minimum initial amount of energy you will need to finish all the tasks.



Example 1:

Input: tasks = [[1,2],[2,4],[4,8]]
Output: 8
Explanation:
Starting with 8 energy, we finish the tasks in the following order:
    - 3rd task. Now energy = 8 - 4 = 4.
    - 2nd task. Now energy = 4 - 2 = 2.
    - 1st task. Now energy = 2 - 1 = 1.
Notice that even though we have leftover energy, starting with 7 energy does not work because we cannot do the 3rd task.
Example 2:

Input: tasks = [[1,3],[2,4],[10,11],[10,12],[8,9]]
Output: 32
Explanation:
Starting with 32 energy, we finish the tasks in the following order:
    - 1st task. Now energy = 32 - 1 = 31.
    - 2nd task. Now energy = 31 - 2 = 29.
    - 3rd task. Now energy = 29 - 10 = 19.
    - 4th task. Now energy = 19 - 10 = 9.
    - 5th task. Now energy = 9 - 8 = 1.
Example 3:

Input: tasks = [[1,7],[2,8],[3,9],[4,10],[5,11],[6,12]]
Output: 27
Explanation:
Starting with 27 energy, we finish the tasks in the following order:
    - 5th task. Now energy = 27 - 5 = 22.
    - 2nd task. Now energy = 22 - 2 = 20.
    - 3rd task. Now energy = 20 - 3 = 17.
    - 1st task. Now energy = 17 - 1 = 16.
    - 4th task. Now energy = 16 - 4 = 12.
    - 6th task. Now energy = 12 - 6 = 6.


Constraints:

1 <= tasks.length <= 105
1 <= actual​i <= minimumi <= 104

我在写贪心的时候,贪心条件错了,这题最最关键的是贪心的核心,应该是

按 (minimum - actual) 从大到小排序

因为:

一个任务如果 minimum - actual 越大,说明它对“启动时能量”的要求越苛刻,越早做

因为这说明,这个任务,启动条件和真实消耗差距比较大,比如真实只消耗 1 的任务,却需要你的能量储备100;反而 actual 和 minimum 接近说明。你不需要额外能量,可以留到后面再做。


这是这题核心贪心结论。


我是贪心和二分,


  1. class Solution:
  2.     def minimumEffort(self, tasks: List[List[int]]) -> int:
  3.         s_actuals, s_min = 0, 0
  4.         tasks = sorted(tasks, key=lambda x: x[1] - x[0], reverse = True)
  5.         
  6.         for t in tasks:
  7.             s_actuals += t[0]
  8.             s_min += t[1]
  9.         
  10.         def check(energy):
  11.             for t in tasks:
  12.                 if energy < t[1]:
  13.                     return False
  14.                 else:
  15.                     energy -= t[0]
  16.             return True

  17.         left, right = s_actuals, s_min

  18.         while left < right:
  19.             mid = (left + right) // 2

  20.             if check(mid):
  21.                 right = mid
  22.             else:
  23.                 left = mid + 1

  24.         return left


复制代码
但是可以直接贪心!
  1. class Solution:
  2.     def minimumEffort(self, tasks: List[List[int]]) -> int:

  3.         tasks.sort(key=lambda x: x[1] - x[0], reverse=True)

  4.         ans = 0
  5.         energy = 0

  6.         for actual, minimum in tasks:

  7.             if energy < minimum:
  8.                 ans += minimum - energy
  9.                 energy = minimum

  10.             energy -= actual

  11.         return ans
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-14 10:00:25 | 只看该作者
全局:
LC. 2784. Check if Array is Good

解法
  1. class Solution:
  2.     def isGood(self, nums: List[int]) -> bool:
  3.         n = len(nums)
  4.         n_max  = max(nums)

  5.         if n != n_max + 1:
  6.             return False

  7.         freq = Counter(nums)

  8.         for i in range(1, n_max):
  9.             if freq[i] != 1:
  10.                 return False
  11.         
  12.         if freq[n_max] != 2:
  13.             return False
  14.         
  15.         return True
复制代码
排序法虽然哈希表(Counter)的时间复杂度是 $O(N)$,是最优的,但在这种规模很小(N < 100)的题目中,排序法往往更简洁,不容易出错,且不需要额外的 O(N) 空间(如果不计排序本身的开销)。我们可以直接构造出理想中的 base[n],然后跟排序后的 nums 对比:
  1. class Solution:
  2.     def isGood(self, nums: List[int]) -> bool:
  3.         # 1. 确定预期的 n 是多少
  4.         n = len(nums) - 1
  5.         
  6.         # 2. 如果 n < 1,根据约束虽然不会发生,但逻辑上要严谨
  7.         if n <= 0:
  8.             return False
  9.             
  10.         # 3. 构造预期的数组:[1, 2, ..., n-1, n, n]
  11.         target = list(range(1, n)) + [n, n]
  12.         
  13.         # 4. 排序对比
  14.         return sorted(nums) == target
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-17 08:22:50 | 只看该作者
全局:
LC. 1306. Jump Game III

看起来像 DP,但是其实是 BFS。。。

穷尽从 start 出发的每一个可能到达的 index 和 index-arr[index] and index + arr[index]
  1. from collections import deque

  2. class Solution:
  3.     def canReach(self, arr: List[int], start: int) -> bool:
  4.         n = len(arr)
  5.         visited = [False] * n
  6.         queue = deque([start])
  7.         visited[start] = True   # ⭐ 提前标记

  8.         while queue:
  9.             curr = queue.popleft()

  10.             if arr[curr] == 0:
  11.                 return True

  12.             for ind in (curr - arr[curr], curr + arr[curr]):
  13.                 if 0 <= ind < n and not visited[ind]:
  14.                     visited[ind] = True   # ⭐ 入队即标记
  15.                     queue.append(ind)

  16.         return False
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-18 02:51:47 | 只看该作者
全局:
LC. 3931. Check Adjacent Digit Differences
  1. class Solution:
  2.     def isAdjacentDiffAtMostTwo(self, s: str) -> bool:
  3.         n = len(s)

  4.         for i in range(n-1):
  5.             if abs(int(s[i]) - int(s[i+1])) > 2:
  6.                 return False

  7.         return True
  8.         
复制代码
当然 Python 处理 “前后配对” 可以用 zip
  1. class Solution:
  2.     def isAdjacentDiffAtMostTwo(self, s: str) -> bool:
  3.         # zip(s, s[1:]) 可以直接把相邻的字符两两配对
  4.         # 例如 s = "132", zip 后得到 ('1', '3') 和 ('3', '2')
  5.         for c1, c2 in zip(s, s[1:]):
  6.             if abs(int(c1) - int(c2)) > 2:
  7.                 return False
  8.         return True
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-18 03:12:59 | 只看该作者
全局:
LC.3932. Count K-th Roots in a Range

我是直接用 开 K 次方来做,其实会有精度问题,当然因为 Leetcode ,所以提交后除了问题我打了补丁,但是还是不太优秀的解法。
  1. class Solution:
  2.     def countKthRoots(self, l: int, r: int, k: int) -> int:
  3.         ans = 0
  4.         if l == 0:
  5.             min_l = 0
  6.         else:
  7.             min_l = int(exp( log(l) / k ))

  8.         if r == 0:
  9.             max_r = 0
  10.         else:
  11.             max_r = int(exp( log(r) / k ))

  12.         ans = max_r - min_l

  13.         if l <= min_l ** k <= r: ans += 1
  14.         if l <= (max_r+1) ** k <= r: ans += 1
  15.         return ans
复制代码
更好的解法,

求 [l, r] 区间内满足条件的个数,可以转化为:

在 [0, r] 内满足条件的个数 - 在  [0, l-1] 内满足条件的个数


这样我们就只需要写一个专门求 [0, limit] 范围内完美 k 次方个数的辅助函数。

辅助函数 count_up_to(limit),我们要求的是满足 x^k < limit  的最大整数 x。
因为 x^k 是一个单调递增的函数,我们可以直接在 [0, limit] 的范围内进行二分查找。纯整数乘法绝对不会有精度问题!
  1. class Solution:
  2.     def countKthRoots(self, l: int, r: int, k: int) -> int:
  3.         
  4.         # 辅助函数:计算范围 [0, limit] 内有多少个完美 k 次幂
  5.         def count_up_to(limit: int) -> int:
  6.             if limit < 0:
  7.                 return 0
  8.             
  9.             left, right = 0, limit
  10.             max_x = 0
  11.             
  12.             # 纯整数二分查找,寻找满足 x^k <= limit 的最大 x
  13.             while left <= right:
  14.                 mid = (left + right) // 2
  15.                 if mid ** k <= limit:
  16.                     max_x = mid      # mid 是合法的,记录下来
  17.                     left = mid + 1   # 尝试找更大的
  18.                 else:
  19.                     right = mid - 1  # mid 太大了,缩小范围
  20.                     
  21.             # 整数范围是 [0, max_x],所以总个数是 max_x + 1
  22.             return max_x + 1

  23.         # 核心逻辑:用前缀相减的思想
  24.         return count_up_to(r) - count_up_to(l - 1)
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-20 10:07:40 | 只看该作者
全局:
LC. 2657. Find the Prefix Common Array of Two Arrays

没看懂第一句话,

0-indexed integer permutations A and B of length n


这个其实就是说,是0~n-1 之间的数的某个排列。

每个数字只出现一次。

我的解法相当于强做,
  1. class Solution:
  2.     def findThePrefixCommonArray(self, A: List[int], B: List[int]) -> List[int]:
  3.         
  4.         C = []
  5.         freqA = defaultdict(int)
  6.         freqB = defaultdict(int)

  7.         for i in range(len(A)):
  8.             freqA[A[i]] += 1
  9.             freqB[B[i]] += 1
  10.             curr = 0
  11.             common_keys = set(freqA.keys()).intersection(set(freqB.keys()))
  12.             for j in common_keys:
  13.                 curr += min(freqA[j], freqB[j])
  14.             C.append(curr)
  15.         
  16.         return C

复制代码
但是如果利用上排列的性质,其实可以更加容易的求解。

既然每个数字在 A 和 B 里最多各出现一次,那我们可以把两个哈希表合并成一个通用的 seen 频次表(或者一个长度为 $n+1$ 的数组/集合)。当我们同时遍历 A 和 B 到位置 i 时,我们会遇到两个数:A[i] 和 B[i]。我们把这两个数扔进 seen 里(频次加 1)。关键逻辑:如果某个数字的频次变成了 2,说明它在 A 的前缀里出现过一次,在 B 的前缀里也出现过一次。它就是我们要找的“公共元素”!我们只需要用一个全局计数器 common_count,每当看到频次变 2,就把计数器加 1。这样每次循环直接把 common_count 放进答案即可,不需要每一步都去重新遍历、求交集。
  1. class Solution:
  2.     def findThePrefixCommonArray(self, A: List[int], B: List[int]) -> List[int]:
  3.         n = len(A)
  4.         C = []
  5.         
  6.         # 因为数字是 1 到 n,我们可以用一个大小为 n + 1 的列表代替哈希表,效率更高
  7.         count = [0] * (n + 1)
  8.         common_count = 0
  9.         
  10.         for i in range(n):
  11.             # 1. 处理 A[i]
  12.             count[A[i]] += 1
  13.             if count[A[i]] == 2:
  14.                 common_count += 1
  15.                
  16.             # 2. 处理 B[i]
  17.             count[B[i]] += 1
  18.             if count[B[i]] == 2:
  19.                 common_count += 1
  20.             
  21.             # 3. 当前位置的答案就是累加的 common_count
  22.             C.append(common_count)
  23.             
  24.         return C
复制代码
或者用 set
  1. class Solution:
  2.     def findThePrefixCommonArray(self, A: List[int], B: List[int]) -> List[int]:
  3.         n = len(A)
  4.         C = []
  5.         seen = set()
  6.         common_count = 0
  7.         
  8.         for i in range(n):
  9.             # 如果 A[i] 已经在 seen 里了,说明 B 之前出过这个数
  10.             if A[i] in seen:
  11.                 common_count += 1
  12.             else:
  13.                 seen.add(A[i])
  14.                
  15.             # 如果 B[i] 已经在 seen 里了,说明 A 之前(或者刚才)出过这个数
  16.             if B[i] in seen:
  17.                 common_count += 1
  18.             else:
  19.                 seen.add(B[i])
  20.                
  21.             C.append(common_count)
  22.             
  23.         return C
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-21 10:53:35 | 只看该作者
全局:
LC 3043. Find the Length of the Longest Common Prefix

看到 prefix 第一个想法, Tire Tree 但是感觉太复杂了。

把 arr1 的所有数字当成字符串插入到字典树中,然后拿 arr2 的数字去树里跑匹配,走到哪一步断掉,就是最长前缀。


然后这道题的规模决定了一定不能暴力做,arr1 和 arr2 的长度都高达 5 x 10^4。如果用暴力双重循环去两两比较,操作次数是 2.5 x 10^9,绝对会超时。

然后的一个关键观察是,

注意看 Constraints,数字最大是10^8。这意味着每个数字最多只有 8 位数,也就是说,一个数字最多只有 8 个前缀!


说实话我没注意到一开始,看了 hint 才发现的。

哈希表存前缀
1. 分解 arr1:遍历 arr1 中的每一个数字,把它所有的前缀都拆出来,扔进一个 HashSet 里。(比如对于 123,我们把 123、12、1 都加入 Set)。
2. 匹配 arr2:遍历 arr2 中的每一个数字,也把它从长到短拆成前缀。对于每一个前缀,去 Set 里查一下是否存在。一旦在 Set 中查到了,这就是当前数字能匹配到的最长前缀,更新最大长度,然后直接 break 看下一个数字。

code

class Solution:
    def longestCommonPrefix(self, arr1: List[int], arr2: List[int]) -> int:
        prefix = set()

        for num in arr1:
            str_num = str(num)
            for i in range(len(str_num)):
                prefix.add(str_num[:i+1])
        ans = 0

        for num in arr2:
            str_num = str(num)
            for i in range(len(str_num)):
                if str_num[:i+1] in prefix:
                    ans = max(ans, i+1)
        
        return ans

        





优化 1: 提前剪枝(Pruning)

其实就是遍历 arr2 的时候倒过来
  1. class Solution:
  2.     def longestCommonPrefix(self, arr1: List[int], arr2: List[int]) -> int:
  3.         prefix = set()

  4.         # Step 1: 存入 arr1 的所有前缀(你的原逻辑)
  5.         for num in arr1:
  6.             str_num = str(num)
  7.             for i in range(len(str_num)):
  8.                 prefix.add(str_num[:i+1])
  9.                
  10.         ans = 0

  11.         # Step 2: 匹配 arr2,从长到短找,找到就 break
  12.         for num in arr2:
  13.             str_num = str(num)
  14.             # 优化:只检查长度大于 ans 的前缀,如果连最长前缀都不够 ans,直接跳过
  15.             if len(str_num) <= ans:
  16.                 continue
  17.                
  18.             # 从最长 (len(str_num)) 到最短 (ans + 1) 逆序检查
  19.             for i in range(len(str_num), ans, -1):
  20.                 if str_num[:i] in prefix:
  21.                     ans = max(ans, i)
  22.                     break # 找到当前数字的最长前缀了,直接结束内层循环
  23.         
  24.         return ans
复制代码
优化 2: 利用整数除法替代字符串转换
  1. class Solution:
  2.     def longestCommonPrefix(self, arr1: List[int], arr2: List[int]) -> int:
  3.         prefixes = set()
  4.         
  5.         # 纯数字剥离前缀:每次除以 10
  6.         for num in arr1:
  7.             while num > 0:
  8.                 prefixes.add(num)
  9.                 num //= 10
  10.                
  11.         ans = 0
  12.         
  13.         for num in arr2:
  14.             while num > 0:
  15.                 # 一旦找到匹配,就算出长度并 break
  16.                 if num in prefixes:
  17.                     ans = max(ans, len(str(num)))
  18.                     break
  19.                 num //= 10
  20.                
  21.         return ans
复制代码
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-25 11:34:28 来自APP | 只看该作者
全局:
LC. 3940. Limit Occurrences in Sorted Array

其实我想到了应该指针,但是还是有点思路不清晰。

所以先写了一个 working solution, 但是还是不够的。
  1. class Solution:
  2.     def limitOccurrences(self, nums: list[int], k: int) -> list[int]:
  3.         n = len(nums)
  4.         freq = Counter(nums)
  5.         ans = []
  6.         keys = sorted(list(set(nums)))

  7.         for key in keys:
  8.             if freq[key] < k:
  9.                 ans += [key] * freq[key]
  10.             else:
  11.                 ans += [key] * k

  12.         return ans
复制代码
存在的优化空间(没有充分利用题目条件):

忽略了“有序”特性: 题目明确说明 nums 是一个已排序(sorted)的数组。你使用了 set(nums) 会丢失元素的原始顺序,导致你不得不再次使用 sorted()。这会让这部分的时间复杂度从 O(N) 退化到 O(N log N)。

空间复杂度: Counter 需要额外的哈希表空间,keys 需要额外的数组空间,整体空间复杂度是 O(N)。而题目的 Follow-up 明确问了:你能用 O(1) 的额外空间原地(in-place)解决吗?


最好的解法

核心原理:
既然数组是有序的,那么相同的元素一定紧挨在一起。
假设我们要求最多保留 k 个相同的元素,那么我们只需要比较:当前正在遍历的元素,和我们“已经决定保留”的倒数第 k 个元素是否相等?

如果不相等: 说明当前元素的出现次数还没达到 k 次,可以保留。

如果相等: 说明在此之前已经有了 k 个相同的元素(因为数组是有序的),当前元素必须丢弃。

🛠️ 满分解法:O(1) 空间原地修改
按照上述思路,我们可以使用快慢指针(Slow & Fast Pointers)。

slow 指针:指向下一个可以存放合法元素的位置。(也代表当前已经保留的元素个数)

fast 指针:遍历原数组的所有元素。
  1. class Solution:
  2.     def limitOccurrences(self, nums: list[int], k: int) -> list[int]:
  3.         # 如果数组长度小于等于 k,全部保留即可
  4.         if len(nums) <= k:
  5.             return nums
  6.             
  7.         slow = 0
  8.         
  9.         # fast 指针遍历所有元素
  10.         for fast in range(len(nums)):
  11.             # 前 k 个元素无条件保留
  12.             # 或者当前元素不等于已经保留的倒数第 k 个元素
  13.             if slow < k or nums[fast] != nums[slow - k]:
  14.                 nums[slow] = nums[fast]
  15.                 slow += 1  # 慢指针向前走一步
  16.                
  17.         # 题目要求返回结果数组,有些语言不支持直接修改大小,
  18.         # 在 Python 中我们可以切片返回被修改后的前 slow 个元素
  19.         return nums[:slow]
复制代码

补充内容 (2026-05-25 11:38 +08:00):
一步步把
  1. nums = [1, 1, 1, 2]
复制代码
  1. k = 2
复制代码
的前 3 步(顺便把最后 1 步也走完)拆解开来。
核心判断条件是:
  1. if slow < 2 or nums[fast] != nums[slow - 2]:
复制代码
    1. slow < 2
    复制代码
    :因为最多允许保留 2 个相同元素,所以数组的前 2 个元素我们无条件保留
    1. nums[fast] != nums[slow - 2]
    复制代码
    :如果当前遍历到的元素
    1. nums[fast]
    复制代码
    ,和我们已经决定保留的倒数第 2 个元素(即
    1. nums[slow - 2]
    复制代码
    )不相等,说明当前元素还没达到 2 次上限,可以保留。


  1. fast
复制代码
指向第三个
  1. 1
复制代码
时,程序去检查了
  1. nums[slow - 2]
复制代码
也就是
  1. nums[0]
复制代码
。发现
  1. nums[0]
复制代码
也是
  1. 1
复制代码
。 因为数组是有序的,如果
  1. nums[slow - 2]
复制代码
已经是
  1. 1
复制代码
了,那中间的
  1. nums[slow - 1]
复制代码
肯定也是
  1. 1
复制代码
。这意味着如果我们再把当前的
  1. 1
复制代码
放进去,就会出现连续 3 个
  1. 1
复制代码
,违反了
  1. k = 2
复制代码
的限制。
所以,慢指针
  1. slow
复制代码
停在索引 2 的位置“拒绝接收”第三个
  1. 1
复制代码
,直到
  1. fast
复制代码
找到了数字
  1. 2
复制代码
,才把它覆盖到了索引 2 的位置上。最后我们返回
  1. nums[:3]
复制代码
,也就是
  1. [1, 1, 2]
复制代码
,完美解决!
回复

使用道具 举报

🔗
 楼主| Myron2017 2026-5-26 09:49:25 | 只看该作者
全局:
LC. 3121. Count the Number of Special Characters II

还是可以学习的。

我的解法
  1. class Solution:
  2.     def numberOfSpecialChars(self, word: str) -> int:
  3.         index_dict_list = defaultdict(list)
  4.         small_letters = []

  5.         for ind, ch in enumerate(word):
  6.             index_dict_list[ch].append(ind)
  7.             if ch.islower() and ch not in small_letters:
  8.                 small_letters.append(ch)
  9.         
  10.         ans = 0
  11.         
  12.         for ch in small_letters:
  13.             if ch.upper() in index_dict_list and index_dict_list[ch][-1] < index_dict_list[ch.upper()][0]:
  14.                 ans += 1
  15.         
  16.         return ans
复制代码
但是,

我们只关心小写的最后一次索引和大写的第一次索引,我们完全不需要把中间的索引都存下来!我们可以一边遍历,一边动态更新这两个极值。
  1. class Solution:
  2.     def numberOfSpecialChars(self, word: str) -> int:
  3.         # 只记录关键索引,空间复杂度降为 O(1) (最多各存 26 个键值对)
  4.         last_lower = {}
  5.         first_upper = {}
  6.         
  7.         for i, ch in enumerate(word):
  8.             if ch.islower():
  9.                 # 不断覆盖,遍历结束时存的一定是“最后一次”的索引
  10.                 last_lower[ch] = i
  11.             else:
  12.                 # 只有当大写字母还没出现过时才记录,保证是“第一次”的索引
  13.                 if ch not in first_upper:
  14.                     first_upper[ch] = i
  15.                     
  16.         ans = 0
  17.         
  18.         # 遍历所有出现过的小写字母
  19.         for ch in last_lower:
  20.             upper_ch = ch.upper()
  21.             # 必须满足两个条件:
  22.             # 1. 对应的大写字母存在
  23.             # 2. 小写的最后一次索引 < 大写的第一次索引
  24.             if upper_ch in first_upper and last_lower[ch] < first_upper[upper_ch]:
  25.                 ans += 1
  26.                
  27.         return ans
复制代码
回复

使用道具 举报

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

本版积分规则

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