检查相同字母间的距离

169 阅读3分钟

🎈 算法并不一定都是很难的题目,也有很多只是一些代码技巧,多进行一些算法题目的练习,可以帮助我们开阔解题思路,提升我们的逻辑思维能力,也可以将一些算法思维结合到业务代码的编写思考中。简而言之,平时进行的算法习题练习带给我们的好处一定是不少的,所以让我们一起来养成算法练习的习惯。今天练习的题目是一道比较简单的题目 ->检查相同字母间的距离

问题描述

给你一个下标从  0  开始的字符串  s ,该字符串仅由小写英文字母组成,s  中的每个字母都  恰好  出现  两次 。另给你一个下标从  0  开始、长度为  26  的的整数数组  distance 。

字母表中的每个字母按从  0  到  25  依次编号(即,'a' -> 0'b' -> 1'c' -> 2, ... , 'z' -> 25)。

在一个  匀整  字符串中,第  i  个字母的两次出现之间的字母数量是  distance[i] 。如果第  i  个字母没有在  s  中出现,那么  distance[i]  可以  忽略 。

如果  s  是一个  匀整  字符串,返回  true ;否则,返回  false 。

示例 1:

输入: s = "abaccb", distance = [1,3,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出: true
解释:
- 'a' 在下标 0 和下标 2 处出现,所以满足 distance[0] = 1 。
- 'b' 在下标 1 和下标 5 处出现,所以满足 distance[1] = 3 。
- 'c' 在下标 3 和下标 4 处出现,所以满足 distance[2] = 0 。
注意 distance[3] = 5 ,但是由于 'd' 没有在 s 中出现,可以忽略。
因为 s 是一个匀整字符串,返回 true

示例 2:

输入: s = "aa", distance = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出: false
解释:
- 'a' 在下标 0 和 1 处出现,所以两次出现之间的字母数量为 0 。
但是 distance[0] = 1 ,s 不是一个匀整字符串。

提示:

  • 2 <= s.length <= 52
  • s  仅由小写英文字母组成
  • s  中的每个字母恰好出现两次
  • distance.length == 26
  • 0 <= distance[i] <= 50

思路分析

首先我们应该要先理解一下题目意思,题目会给我们一个字符串s,我们需要统计s中相同字母出现位置之间的字母数,如aba,字母a之间有一个其他字母。给我们一个数组distance,代表各个字母的之间出现的其他字母的数目,数组长度为 26,分别代表 26 个字母:0 -> a,1 -> b,…… 25 -> z;

我们需要判断给出的数组distance描述与字符串s字符串中各字母之间出现的字母数是否一致。

  • 统计s字符串中各字母之间出现的字母数

我们可以使用一个哈希表记录上一个字母出现的位置下标,当字母出现第二次时直接通过两个下标值就可以计算出它们之间存在的字母数。

const map = {};
for (let i = 0; i < s.length; i++) {
  if (map[s[i]] !== undefined) {
    const ind = s[i].charCodeAt() - 97;
    res[ind] = Math.min(res[ind], i - map[s[i]] - 1);
  }
  map[s[i]] = i;
}
  • 判断计算的与给出的distance描述是否一致

题目中说到:如果第  i  个字母没有在  s  中出现,那么  distance[i]  可以  忽略 ,那么我们只需要判断我们实际有计算到的字母即可,如果实际计算得到的和distance数组中的不一致,则说明 s 不是一个匀整字符串。

for (let i = 0; i < 26; i++) {
  if (res[i] != Infinity && res[i] != distance[i]) return false;
}

AC 代码

完整 AC 代码如下:

/**
 * @param {string} s
 * @param {number[]} distance
 * @return {boolean}
 */
var checkDistances = function (s, distance) {
  const map = {};
  const res = new Array(26).fill(Infinity);
  for (let i = 0; i < s.length; i++) {
    if (map[s[i]] !== undefined) {
      const ind = s[i].charCodeAt() - 97;
      res[ind] = Math.min(res[ind], i - map[s[i]] - 1);
    }
    map[s[i]] = i;
  }
  for (let i = 0; i < 26; i++) {
    if (res[i] != Infinity && res[i] != distance[i]) return false;
  }
  return true;
};

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,在此谢谢大家的支持,我们下文再见 🙌。