题目
给你一个字符串 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 。
提示:
- 1 <= s.length <= 104
- s[i] 和 c 均为小写英文字母
-
思路一:
生成一个与c重复下标的数组:iArray
- 遍历 iArray 然后用 strArray 每一个下标与iArray每一项进行比较
- 如果 strArray 的下标小于等于 iArray第一项
- 说明当前的距离只有离 iArray第一项最近,直接将距离push进去
- 如果当前 strArray 的下标 大于等于 iArray[i + 1]
- 说明 i 的区间需要改变位置了
- 比较大小,取距离最小的
判断边界,如果iArray[i + 1]超出了iArray 那就使用iArray[i]:当前i代表最后索引了
const shortestToChar = function (s, c) {const strArray = s.split('');const iArray = []const res = []// 生成一个与c重复下标的数组:iArraystrArray.forEach((item, index) => {if (item === c) {iArray.push(index)}})// console.log(iArray)// console.log(strArray)// 遍历 iArray 然后用 strArray 每一个下标与iArray每一项进行比较for (let i = 0; i < iArray.length; i++) {for (let j = 0; j < strArray.length; j++) {// 如果 strArray 的下标小于等于 iArray第一项// 说明当前的距离只有离 iArray第一项最近,直接将距离push进去if (j <= iArray[0]) {res.push(Math.abs(j - iArray[i]))} else {// 如果当前 strArray 的下标 大于等于 iArray[i + 1]// 说明 i 的区间需要改变位置了if (j >= iArray[i + 1]) {i = i + 1}// 比较大小,取距离最小的// 判断边界,如果iArray[i + 1]超出了iArray 那就使用iArray[i]:当前i代表最后索引了const min = Math.min(Math.abs(j - iArray[i]), Math.abs((j - iArray[i + 1]) || j - iArray[i]))res.push(min)}}continue}return res};const res = shortestToChar("aaba", "b")console.log(res);
思路二:
把 C 看成分界线,如果没有左边或者右边用 Infinity 替代
- 将 S 划分成一个个窗口。
- 然后对每个窗口进行遍历,分别计算每个字符到窗口边界的距离最小值。

const shortestToChar = function (s, c) {let left = s[0] === c ? 0 : Infinity,right = s.indexOf(c, 1) // 第一个重复的const res = new Array(s.length)console.log(left, right);for (let i = 0; i < s.length; i++) {if (right === i) {left = right// 下一个重复的right = s.indexOf(c, i + 1)}// 从i开始与左右边界比较取绝对值,然后res[i] = Math.min(Math.abs(i - left), Math.abs(i - right))}return res};const res = shortestToChar("aaba", "b")console.log(res)
