所有子字符串美丽值之和

79 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情

1781. 所有子字符串美丽值之和 - 力扣(LeetCode)

一个字符串的 美丽值 定义为:出现频率最高字符与出现频率最低字符的出现次数之差。

  • 比方说,"abaacc" 的美丽值为 3 - 1 = 2 。

给你一个字符串 s ,请你返回它所有子字符串的 美丽值 之和。

示例 1:

输入: s = "aabcb"
输出: 5
解释: 美丽值不为零的字符串包括 ["aab","aabc","aabcb","abcb","bcb"] ,每一个字符串的美丽值都为 1 。

示例 2:

输入: s = "aabcbaa"
输出: 17

提示:

  • 1 <= s.length <= 500
  • s 只包含小写英文字母。

思路

本题可以用双循环求解。外层循环用i作为下标,表示子字符串的起点,内层循环用j作为下标,表示子字符串的终点。因为s只包含小写英文字母,可以用一个长度为26,初始填充值为0的数组cnt来记录子字符串中各个字符出现的频率数,用maxFreq表示当前字符串出现的最高频率数, cnt[s[j]] = cnt[s[j]] + 1maxFreq = max(maxFreq, cnt[s[j]]),最小频率可以通过遍历cnt获得,cut中不为零的最小值就是最小频率数,累加最大频率数和最小频率数之差,就是我们要求的值,代码如下。其实获取最小频率数有更优的解,大家有兴趣的话可以尝试一下。

解题

/**
 * @param {string} s
 * @return {number}
 */
var beautySum = function (s) {
  let res = 0;
  const a = "a".charCodeAt();
  for (let i = 0; i < s.length; i++) {
    const cnt = new Array(26).fill(0);
    let maxFreq = 0;
    for (let j = i; j < s.length; j++) {
      let idx = s.charCodeAt(j) - a;
      cnt[idx]++;
      maxFreq = Math.max(maxFreq, cnt[idx]);
      let minFreq = s.length;
      for (let k = 0; k < 26; k++) {
        if (cnt[k] > 0) {
          minFreq = Math.min(minFreq, cnt[k]);
        }
      }
      res += maxFreq - minFreq;
    }
  }
  return res;
};