统计以给定字符开头和结尾的子字符串总数
难度:
标签:
题目描述
You are given a string s
and a character c
. Return the total number of substrings of s
that start and end with c
.
Example 1:
Input: s = "abada", c = "a"
Output: 6
Explanation: Substrings starting and ending with "a"
are: "abada"
, "abada"
, "abada"
, "abada"
, "abada"
, "abada"
.
Example 2:
Input: s = "zzz", c = "z"
Output: 6
Explanation: There are a total of 6
substrings in s
and all start and end with "z"
.
Constraints:
1 <= s.length <= 105
s
andc
consist only of lowercase English letters.
代码结果
运行时间: 21 ms, 内存: 16.5 MB
/*
* 思路:
* 使用Java Stream API来实现同样的逻辑。
* 首先将字符串s转换成字符流,找到所有字符c出现的索引位置,
* 对于每一个索引位置i,使用一个嵌套流来计算从i开始到后面所有的以字符c结尾的子字符串数量。
*/
import java.util.stream.IntStream;
public class SolutionStream {
public long countSubstrings(String s, char c) {
return IntStream.range(0, s.length())
.filter(i -> s.charAt(i) == c)
.mapToLong(i -> IntStream.range(i, s.length())
.filter(j -> s.charAt(j) == c)
.count())
.sum();
}
public static void main(String[] args) {
SolutionStream sol = new SolutionStream();
System.out.println(sol.countSubstrings("abada", 'a')); // 6
System.out.println(sol.countSubstrings("zzz", 'z')); // 6
}
}
解释
方法:
该题解的核心思路是首先统计字符 c 在字符串 s 中出现的次数 n。然后利用组合数学的知识,计算出所有以字符 c 开头和结尾的子字符串的数量。如果 c 在 s 中出现n次,那么任选两个位置组成的子字符串都将以 c 作为开头和结尾,这样的选择方式共有 C(n, 2) = n*(n-1)/2 种。此外,每个单独的字符 c 本身也是一个符合条件的子字符串,因此总数还要加上 n,即总数为 n*(n+1)/2。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在计算以字符c开头和结尾的子字符串数量时使用组合公式C(n, 2)加上n,而不是其他计算方式?
▷🦆
在计算字符c在字符串s中的出现次数时,如果字符串非常长,是否有更高效的方法来处理大数据量?
▷🦆
该算法假设字符c至少出现一次,如果c在s中一次都没有出现,返回值应该是多少?这个处理在当前的实现中是否正确?
▷