333 words
2 minutes
日拱两卒(三)
2026-07-13

80#

划分字母区间。

把一个字符串分成尽可能多的区间,同一种字母必须出现在同一个区间。

预处理出来每个字母的最左和最右。

从前往后扫,维护必须延伸到的最右边。

class Solution:
def partitionLabels(self, s: str) -> List[int]:
n = len(s)
seg = [[-1] * 2 for _ in range(26)]
for i, ch in enumerate(s):
idx = ord(ch) - ord('a')
if seg[idx][0] == -1:
seg[idx][0] = i
seg[idx][1] = i
ans = []
l = 0
r = seg[ord(s[0]) - ord('a')][1]
i = l
while True:
if r >= n - 1:
ans.append(n - 1 - l + 1)
break
if i > r:
ans.append(r - l + 1)
l = i
r = seg[ord(s[i]) - ord('a')][1]
r = max(r, seg[ord(s[i]) - ord('a')][1])
i += 1
return ans

79#

跳跃游戏II。

问在nums上从0跳到n - 1的最小次数。每一次可以跳0nums[i]之间任意远。

记忆化做法在Leetcode上没被卡。

但本质上和80 划分字母区间是同一道题。

维护当前区间的最远延申位置,每当指针越过这个边界,就完成一次切割或者跳跃。

class Solution:
def jump(self, nums: List[int]) -> int:
n = len(nums)
if n == 1:
return 0
right = [i + nums[i] for i in range(n)]
ans = 0
r = right[0]
max_r = r
i = 0
while True:
if r >= n - 1:
ans += 1
break
if i > r:
ans += 1
r = max_r
continue
max_r = max(max_r, right[i])
i += 1
return ans