821 字符的最短距离
题目
给你一个字符串 s
和一个字符 c
,且 c
是 s
中出现过的字符。
返回一个整数数组 answer
,其中 answer.length == s.length
且 answer[i]
是 s
中从下标 i
到离它 最近的字符 c
的距离 。
两个下标 i
和 j
之间的距离为 abs(i - j)
,其中 abs
是绝对值函数。
示例
示例1:
输入:s = "loveleetcode", c = "e"
输出:[3,2,1,0,1,0,0,1,2,2,1,0]
解释:字符 'e' 出现在下标 3、5、6 和 11 处(下标从 0 开始计数)。
距下标 0 最近的 'e' 出现在下标 3 ,所以距离为 abs(0 - 3) = 3 。
距下标 1 最近的 'e' 出现在下标 3 ,所以距离为 abs(1 - 3) = 2 。
对于下标 4 ,出现在下标 3 和下标 5 处的 'e' 都离它最近,但距离是一样的 abs(4 - 3) == abs(4 - 5) = 1 。
距下标 8 最近的 'e' 出现在下标 6 ,所以距离为 abs(8 - 6) = 2 。
示例2:
输入:s = "aaab", c = "b"
输出:[3,2,1,0]
思路
方法一:创建一个与s
长度相同的列表res
,遍历一遍字符串s
,找到字符为c
的位置并将res
中对应位置置0,然后以这些位置为标准,依次向前后扩散,直到全部遍历完成。
方法二:先将字符串s
正向遍历一遍,找到第一个字符为c
的位置,将res
中的对应位置置0,后面res
第i
位的更新规则为:若s[i]==c
,则res[i]=0
,否则res[i]=res[i-1]+1
;完成正向遍历后,在进行一次反向遍历,更新规则为:若res[i]=-1
,则res[i]=res[i+1]+1
,否则res[i]=min(res[i],res[i+1])
。
代码
方法一:
class Solution:
def shortestToChar(self, s: str, c: str) -> List[int]:
res, queue = [-1] * len(s), []
for i in range(len(s)):
if s[i] == c:
res[i] = 0
queue.append(i)
while queue:
n = len(queue)
for i in range(n):
tmp = queue.pop(0)
if 0 < tmp < len(res) and res[tmp - 1] == -1:
res[tmp - 1] = res[tmp] + 1
queue.append(tmp - 1)
if 0 <= tmp < len(res) -1 and res[tmp + 1] == -1:
res[tmp + 1] = res[tmp] + 1
queue.append(tmp + 1)
return res
方法二:
class Solution:
def shortestToChar(self, s: str, c: str) -> List[int]:
res = [-1] * len(s)
for i in range(len(s)):
if s[i] == c: res[i] = 0
elif i - 1 >= 0 and res[i - 1] != -1: res[i] = res[i - 1] + 1
for i in range(len(s)-2, -1, -1):
res[i] = res[i + 1] + 1 if res[i] == -1 else min(res[i], res[i + 1] + 1)
return res