标题描述:子串分值和-蓝桥杯
#问题描述:
输入格式:
输出格式
示例1:
输出
ababc
输出
28
思路:
暴力可以解决,但会超时,所以要把时间从O(N²)变成O(N),而这时就需要res += (long) (i - lastIndex) * (willIndex - i); //子串个数算法。
AC_CodeByJava
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] arr = new int[26];
long res = 0;
for (int i = 0; i < 26; i++) {
arr[i] = -1;
}
String s = sc.nextLine();
String[] str = s.split("");/*将字符串分割成字符串数组,但一个数组只存储一个字符,还不如直接弄一个字符数组*/
//下次出现的位置默认为字符串末尾,因为同一轮遍历中此值不对结果做贡献
int willIndex = str.length; // ababc = 5,将来出现的位置,直接写字符串长度
for (int i = 0; i < str.length; i++) {
int lastIndex = arr[str[i].charAt(0) - 97]; // -1 代表了在0的左边,而0是没法算上的,所以-1可以给它加上
res += (long) (i - lastIndex) * (willIndex - i); //子串个数算法
/* 这个是公式来的,本来是用来求以某个字符为中心的子串中不含有重复字符的个数(不一定要求中心字符两边左右相等),也利用于这道题 */
//算法核心=(本次出现的位置-上次出现的位置)*(将来最近一次出现的位置-本次出现的位置),
arr[str[i].charAt(0) - 97] = i;
}
System.out.println(res);
}
}