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 。
解题思路:建立左右两个数组,保存当前位置 i 距离最近字符的距离,然后比较大小。
class Solution {
public int[] shortestToChar(String s, char c) {
int[] record = new int[s.length()];
int[] left = new int[s.length()+1];
int[] right = new int[s.length()+1];
int len = s.length();
int j = len + 1;
int k = len + 1;
for(int i = 0; i < len; i++){
if(s.charAt(i) == c){
j = i;
}
left[i] = j;
}
for(int i = len - 1; i >= 0; i--){
if(s.charAt(i) == c){
k = i;
}
right[i] = k;
}
for(int i = 0; i < len ; i++){
if(left[i] != len + 1 && right[i] != len + 1){
int a = Math.abs(left[i] - i);
int b = Math.abs(right[i] - i);
record[i] = Math.min(a,b);
}else if(left[i] == len + 1){
record[i] = Math.abs(right[i] - i);
}else if(right[i] == len + 1){
record[i] = Math.abs(left[i] - i);
}
}
return record;
}
}
改进方法
int len = s.length();
int[] res = new int[len];
Arrays.fill(res,len+1);
for(int i = 0, j = -1; i < len; i++){
if(s.charAt(i) == c){
j = i;
}
if(j != -1){
res[i] = i - j;
}
}
for(int i = len - 1, j = -1; i >= 0; i--){
if(s.charAt(i) == c){
j = i;
}
if(j != -1){
res[i] = Math.min(res[i],j - i);
}
}
return res;