6050. 字符串的总引力
1. 题目
字符串的 引力 定义为:字符串中 不同 字符的数量。
- 例如,"abbca" 的引力为 3 ,因为其中有 3 个不同字符 'a'、'b' 和 'c' 。
给你一个字符串 s ,返回 其所有子字符串的总引力 。
子字符串 定义为:字符串中的一个连续字符序列。
示例 1:
输入:s = "abbca"
输出:28
解释:"abbca" 的子字符串有:
- 长度为 1 的子字符串:"a"、"b"、"b"、"c"、"a" 的引力分别为 1、1、1、1、1,总和为 5 。
- 长度为 2 的子字符串:"ab"、"bb"、"bc"、"ca" 的引力分别为 2、1、2、2 ,总和为 7 。
- 长度为 3 的子字符串:"abb"、"bbc"、"bca" 的引力分别为 2、2、3 ,总和为 7 。
- 长度为 4 的子字符串:"abbc"、"bbca" 的引力分别为 3、3 ,总和为 6 。
- 长度为 5 的子字符串:"abbca" 的引力为 3 ,总和为 3 。
引力总和为 5 + 7 + 7 + 6 + 3 = 28 。
示例 2:
输入:s = "code"
输出:20
解释:"code" 的子字符串有:
- 长度为 1 的子字符串:"c"、"o"、"d"、"e" 的引力分别为 1、1、1、1 ,总和为 4 。
- 长度为 2 的子字符串:"co"、"od"、"de" 的引力分别为 2、2、2 ,总和为 6 。
- 长度为 3 的子字符串:"cod"、"ode" 的引力分别为 3、3 ,总和为 6 。
- 长度为 4 的子字符串:"code" 的引力为 4 ,总和为 4 。
引力总和为 4 + 6 + 6 + 4 = 20 。
提示:
- 1 <= s.length <= 105
- s 由小写英文字母组成
2. 解题思路
2.1 题意理解&公式化表达
设为字符串的吸引力,则题目可以转化为:已知字符串,求。
首先,我们来看一下这个公式的复杂度:外层双循环为;内层,如果采用遍历字符串中元素的方法,那么是。因而总体复杂度为,一下子就超时了。
那应该怎么优化呢?Let's 画图思考!
2.2 使用双计数原理进行优化
我们依然保持外层循环不变,看一下可以如何优化里面的公式。
以s='abbca'
为例,当i=0
时,我们可以画出如下示意图。其中,横向代表j
的取值,纵向代表26个小写字母,方格为1
代表s[i:j+1]
中包含该字母。那么,以i=0
为起点的所有子串的吸引力值=矩阵中1
的个数。
如果我们对矩阵纵向求和,相当于对j
进行遍历,正好对应前述公式。
根据双计数原理,我们还可以横向计数呀。我们对字符进行遍历,也可以对矩阵进行求和。那每行1
的个数如何计算呢?其实就等于n-该字符第一次出现的索引值!
这个索引怎么求?一句话,反向遍历!只要i
是反向遍历,那么每个字符都只需要记录最近一次出现的索引。
2.3 复杂度分析
- 时间复杂度:。为字符集大小
- 空间复杂度:
3. 代码
class Solution:
def appealSum(self, s: str) -> int:
n = len(s)
li = [-1] * 26
res = 0
for i in range(n-1, -1, -1):
li[ord(s[i]) - ord('a')] = i
for idx in li:
if idx != -1:
res += n - idx
return res
网友评论