该题解采用动态规划方法,结合了左右环形搜索策略,以找到拼写关键词所需的最少步数。解题的核心在于维护两个方向上字符的最近出现位置。对于环形字符串s中的每个字符,我们都计算它在顺时针和逆时针方向上到达关键词key中每个字符的最短路径。解决方案中使用了两个动态规划数组left和right,分别记录从当前位置i出发,向左和向右达到关键词key中每个字符的最近下标。动态规划过程从关键词key的最后一个字符向第一个字符逆序处理,对于每个字符,我们计算出从当前位置到下一个关键字符的最少步数,逐渐累加以达到全局最优解。
时间复杂度: O(m * n)
空间复杂度: O(n * 26 + n)
# https://space.bilibili.com/206214
class Solution:
def findRotateSteps(self, s: str, t: str) -> int:
# Convert characters to indices for easier manipulation
s = [ord(c) - ord('a') for c in s]
t = [ord(c) - ord('a') for c in t]
n, m = len(s), len(t)
# Position arrays for left and right character locations
pos = [0] * 26 # Arbitrary initial values
# Determine the last occurrence of each character
for i, c in enumerate(s):
pos[c] = i
left = [None] * n # Closest index to the left for each character
for i, c in enumerate(s):
left[i] = pos[:]
pos[c] = i # Update last position
pos = [0] * 26 # Reset for right side computation
for i in range(n - 1, -1, -1):
pos[s[i]] = i
right = [None] * n # Closest index to the right for each character
for i in range(n - 1, -1, -1):
right[i] = pos[:]
pos[s[i]] = i # Update position
# Record positions of each character in s
pos = [[] for _ in range(26)]
for i, b in enumerate(s):
pos[b].append(i)
f = [0] * n # DP array to store minimal steps to current position
for j in range(m - 1, 0, -1):
c = t[j]
if c == t[j - 1]:
continue # Skip if the character does not change
nf = [0] * n # New DP array for current character
for i in pos[t[j - 1]]: # Traverse through all positions of the previous character
l, r = left[i][c], right[i][c] # Left and right nearest positions
res1 = f[l] + (n - l + i if l > i else i - l) # Calculate steps
res2 = f[r] + (n - i + r if r < i else r - i)
if res2 < res1 : res1 = res2
nf[i] = res1 # Store the minimal steps
f = nf # Move to the next character
if s[0] == t[0]:
return f[0] + m # If first character matches, return steps
c = t[0]
l, r = left[0][c], right[0][c]
return min(f[l] + n - l, f[r] + r) + m # Return the minimal steps required