子串分值和

试题H:子串分值和

【问题描述】

对于一个字符串 S,我们定义 S 的分值 f(S) 为 S 中出现的不同的字符个数。

例如 f(”aba”)=2,f(”abc”)=3,f(”aaa”)=1。 现在给定一个字符串 S[0..n−1](长度为 n),

请你计算对于所有 S 的非空 子串 S[i..j](0≤i≤j<n),f(S[i..j]) 的和是多少。

【输入格式】

输入一行包含一个由小写字母组成的字符串 S

【输出格式】

输出一个整数表示答案。

【样例输入】

ababc

【样例输出】

28

【样例说明】

子串 	  f值
a 	    1
ab 	    2
aba 	    2
abab 	    2
ababc 	    3
b 	    1
ba          2
bab         2
babc        3
a           1
ab          2
abc         3
b           1
bc          2
c           1 

思路:

对于每一个子串的分值,只有第一次出现在内的字符才会对该子串有贡献。例如子串“ababc”其内有贡献的是字符abc。那么假设数组last[i]表示字符i上一次出现的位置,则字符s[i]有贡献的子字符串为[last[i]+1,i]和[i,n]组成的子字符串,共有(i-last[i])*(n-i+1)。

import java.util.*;
public class Main {
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            String str =cin.next();
            int[] a = new int[30];
            
            long ans = 0;
            int n = str.length();
            str = " " + str;
            for(int i=1;i<=n;++i) {
                ans+=(i-a[str.charAt(i)-'a'])*(long)1*(n-i+1);
                a[str.charAt(i)-'a']=i;
            }
            System.out.println(ans);
        }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值