给你一个字符串 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]
提示:
1 <= s.length <= 104
s[i]
和c
均为小写英文字母- 题目数据保证
c
在s
中至少出现一次
方法一:两次遍历
两次遍历,找出每个字符左侧和右侧最近的 c,算出最短距离。
方法二:BFS
在字符串 s 中找出所有字符 c 对应的下标,并放入队列 q。
BFS 向左右两边扩散,找出最短距离。
class Solution:
def shortestToChar(self, s: str, c: str) -> List[int]:
n = len(s)
ans = [0] * n
j = inf
for i, ch in enumerate(s):
if ch == c:
j = i
ans[i] = abs(i - j)
j = inf
for i in range(n - 1, -1, -1):
if s[i] == c:
j = i
ans[i] = min(ans[i], abs(i - j))
return ans
class Solution:
def shortestToChar(self, s: str, c: str) -> List[int]:
q = deque([i for i, ch in enumerate(s) if ch == c])
ans = [0 if ch == c else -1 for ch in s]
d = 0
while q:
d += 1
for _ in range(len(q)):
i = q.popleft()
for j in (i - 1, i + 1):
if 0 <= j < len(s) and ans[j] == -1:
ans[j] = d
q.append(j)
return ans
class Solution {
public int[] shortestToChar(String s, char c) {
int n = s.length();
int[] ans = new int[n];
for (int i = 0, j = Integer.MAX_VALUE; i < n; ++i) {
if (s.charAt(i) == c) {
j = i;
}
ans[i] = Math.abs(i - j);
}
for (int i = n - 1, j = Integer.MAX_VALUE; i >= 0; --i) {
if (s.charAt(i) == c) {
j = i;
}
ans[i] = Math.min(ans[i], Math.abs(i - j));
}
return ans;
}
}
class Solution {
public int[] shortestToChar(String s, char c) {
Deque<Integer> q = new ArrayDeque<>();
int n = s.length();
int[] ans = new int[n];
Arrays.fill(ans, -1);
for (int i = 0; i < n; ++i) {
if (s.charAt(i) == c) {
q.offer(i);
ans[i] = 0;
}
}
int d = 0;
while (!q.isEmpty()) {
++d;
for (int t = q.size(); t > 0; --t) {
int i = q.poll();
for (int j : Arrays.asList(i - 1, i + 1)) {
if (j >= 0 && j < n && ans[j] == -1) {
ans[j] = d;
q.offer(j);
}
}
}
}
return ans;
}
}
function shortestToChar(s: string, c: string): number[] {
const n = s.length;
let ans = [];
let pre = Infinity;
for (let i = 0; i < n; i++) {
if (s.charAt(i) == c) pre = i;
ans[i] = Math.abs(pre - i);
}
pre = Infinity;
for (let i = n - 1; i > -1; i--) {
if (s.charAt(i) == c) pre = i;
ans[i] = Math.min(Math.abs(pre - i), ans[i]);
}
return ans;
}
function shortestToChar(s: string, c: string): number[] {
const n = s.length;
const idxs = [];
for (let i = 0; i < n; i++) {
if (s[i] === c) {
idxs.push(i);
}
}
idxs.push(Infinity);
const res = new Array(n);
let i = 0;
for (let j = 0; j < n; j++) {
if (Math.abs(idxs[i] - j) > Math.abs(idxs[i + 1] - j)) {
i++;
}
res[j] = Math.abs(idxs[i] - j);
}
return res;
}
impl Solution {
pub fn shortest_to_char(s: String, c: char) -> Vec<i32> {
let c = c as u8;
let s = s.as_bytes();
let n = s.len();
let mut res = vec![i32::MAX; n];
let mut pre = i32::MAX;
for i in 0..n {
if s[i] == c {
pre = i as i32;
}
res[i] = i32::abs(i as i32 - pre);
}
pre = i32::MAX;
for i in (0..n).rev() {
if s[i] == c {
pre = i as i32;
}
res[i] = res[i].min(i32::abs(i as i32 - pre));
}
res
}
}
class Solution {
public:
vector<int> shortestToChar(string s, char c) {
int n = s.size();
vector<int> ans(n);
for (int i = 0, j = INT_MAX; i < n; ++i) {
if (s[i] == c) j = i;
ans[i] = abs(i - j);
}
for (int i = n - 1, j = INT_MAX; i >= 0; --i) {
if (s[i] == c) j = i;
ans[i] = min(ans[i], abs(i - j));
}
return ans;
}
};
class Solution {
public:
vector<int> shortestToChar(string s, char c) {
int n = s.size();
vector<int> ans(n, -1);
queue<int> q;
for (int i = 0; i < n; ++i)
{
if (s[i] == c)
{
q.push(i);
ans[i] = 0;
}
}
int d = 0;
while (!q.empty())
{
++d;
for (int t = q.size(); t > 0; --t)
{
int i = q.front();
q.pop();
vector<int> dirs{i - 1, i + 1};
for (int& j : dirs)
{
if (j >= 0 && j < n && ans[j] == -1)
{
ans[j] = d;
q.push(j);
}
}
}
}
return ans;
}
};
func shortestToChar(s string, c byte) []int {
n := len(s)
ans := make([]int, n)
for i, j := 0, -10000; i < n; i++ {
if s[i] == c {
j = i
}
ans[i] = i - j
}
for i, j := n-1, 10000; i >= 0; i-- {
if s[i] == c {
j = i
}
if j-i < ans[i] {
ans[i] = j - i
}
}
return ans
}
func shortestToChar(s string, c byte) []int {
n := len(s)
var q []int
ans := make([]int, n)
for i := range s {
ans[i] = -1
if s[i] == c {
q = append(q, i)
ans[i] = 0
}
}
d := 0
for len(q) > 0 {
d++
for t := len(q); t > 0; t-- {
i := q[0]
q = q[1:]
for _, j := range []int{i - 1, i + 1} {
if j >= 0 && j < n && ans[j] == -1 {
ans[j] = d
q = append(q, j)
}
}
}
}
return ans
}