力扣 - 821. 字符的最短距离
题目
思路1
-
使用一个res数组,而且要初始化为Integer.MAX_VALUE
-
从左到右遍历字符串,直到遇到我们的目标字符时候停下来
-
以目标字符为中心,pre和next双指针向两边移动,并且给数组赋值,从1开始递增
-
如果指针再移动过程中遇到当前的值大于等于左边/右边的值,那么就结束该指针的移动

代码
class Solution {
public int[] shortestToChar(String S, char C) {
int len = S.length();
int[] res = new int[len];
// 填充最大值
Arrays.fill(res, Integer.MAX_VALUE);
for (int i = 0; i < len; i++) {
//每次遇到e时候,就进行pre和next的移动
if (S.charAt(i) == C) {
res[i] = 0;
int pre = i-1;
int next = i+1;
int t = 1;
// 赋值的条件是t要小于等于前一个/后一个元素的值
// 进行左移动赋值
while (pre >= 0 && t < res[pre]) {
res[pre--] = t++;
}
t = 1;
// 进行右移动赋值
while (next < len && t < res[next]) {
res[next++] = t++;
}
}
}
// 得到结果
return res;
}
}
复杂度分析
- 时间复杂度:\(O(N^2)\),其中 N 为字符串长度。
- 空间复杂度:\(O(N)\),其中 N 为res数组长度
思路2
- 正向遍历一次,反向遍历一次
- 用
pre标记出现目标字符的位置,利用i的自增,同时给数组赋值 - 正向遍历是给目标字符之后到下一个目标字符之前进行赋值,反向遍历则相反
代码
class Solution {
public int[] shortestToChar(String s, char c) {
int len = s.length();
int[] res = new int[len];
// 必须要除以2,因为Integer.MIN_VALUE已经是最小值了,又因为i>=0,所以 i-pre 会超过整型最大值
int pre = Integer.MIN_VALUE / 2;
// 正向遍历
for (int i = 0; i < len; i++) {
if (s.charAt(i) == c) {
pre = i;
}
res[i] = i - pre;
}
// 反向遍历
pre = Integer.MAX_VALUE;
for (int i = len - 1; i >= 0; i--) {
if (s.charAt(i) == c) {
pre = i;
}
res[i] = Math.min(res[i], pre - i);
}
return res;
}
}
复杂度分析
- 时间复杂度:\(O(N)\),其中 N 为字符串长度。
- 空间复杂度:\(O(N)\),其中 N 为res数组长度
我走得很慢,但我从不后退!

浙公网安备 33010602011771号