【Day 2 】2021-05-11 - 821. 字符的最短距离

题目描述

入选理由

  1. 仍然是一道简单题,不过比昨天的题目难度增加一点
  2. 虽然这是一个字符串的题目,但其实字符串和数组没有本质差别,这在讲义中也提到了。

题目描述

给定一个字符串 S 和一个字符 C。返回一个代表字符串 S 中每个字符到字符串 S 中的字符 C 的最短距离的数组。

示例 1:

输入: S = "loveleetcode", C = 'e'
输出: [3, 2, 1, 0, 1, 0, 0, 1, 2, 2, 1, 0]
说明:

- 字符串 S 的长度范围为 [1, 10000]。
- C 是一个单字符,且保证是字符串 S 里的字符。
- S 和 C 中的所有字母均为小写字母。

我的回答

https://github.com/leetcode-pp/91alg-3/issues/4#issuecomment-771297588

解法一

时空复杂度

时间复杂度:O(n^2)

空间复杂度: O(1)

两层遍历,第一层定位坐标,第二层向前向后分别找到一个相同的值后进行距离比较

/**
 * @param {string} S
 * @param {character} C
 * @return {number[]}
 */
var shortestToChar = function (S, C) {
    let res = []
    for (let i = 0; i < S.length; i++) {
        if (S[i] === C) {
            res.push(0)
            continue
        }
        let l = i; r = i; short = Infinity
        while (l >= 0) {
            if (S[l] === C) {
                short = i - l
                break
            }
            l--
        }
        while (r < S.length) {
            if (S[r] === C) {
                short = Math.min(short, r - i)
                break
            }
            r++
        }
        res.push(short)
    }
    return res
};

解法二

时间复杂度:O(n)

空间复杂度: O(1)

var shortestToChar = function (s, c) {
    let res = []
    let carry = - Infinity
    for (let i = 0; i < s.length; i++) {
        if (s[i] === c) carry = i
        res[i] = Math.min(i - carry, res[i] || Infinity)
 
    }
 
    let orCarry = Infinity
    for (let i = s.length - 1; i >= 0; i--) {
        if (s[i] === c) orCarry = i
        res[i] = Math.min(orCarry - i, res[i])
    }
    return res
};

解法二

时空复杂度

时间复杂度:O(n)

空间复杂度: O(1)

从上面我们可以看出很多比较都是可以省略的,比如向前找到了以后,没遇到下一个相同字符串前都只需要加一即可,那我们就通过向前向后分别得出距离后比较

var shortestToChar = function (S, C) {
    let arr = Array(S.length)
    for (let i = 0; i < S.length; i++) {
        if (S[i] === C) arr[i] = 0
        else arr[i] = arr[i - 1] === void 0 ? Infinity : arr[i - 1] + 1
    }
    for (let i = S.length - 1; i >= 0; i--) {
        if (arr[i] === Infinity || arr[i + 1] + 1 < arr[i]) arr[i] = arr[i + 1] + 1
    }
 
    return arr
};

参考回答