蓝桥杯:子串分值

该文描述了一道编程题,要求计算给定字符串所有非空子串中恰好出现一次的字符个数之和。初始的暴力解法可能会超时,但可以通过优化,使用两层循环和双指针技术来提高效率,计算每个字符对结果的贡献并累加,从而得到正确答案。
摘要由CSDN通过智能技术生成

题目描述

对于一个字符串 �S,我们定义 �S 的分值 �(�)f(S) 为 �S 中恰好出现一次的字符个数。例如 �(���)=1,�(���)=3,�(���)=0f(aba)=1,f(abc)=3,f(aaa)=0。

现在给定一个字符串 �0⋯�−1S0⋯n−1(长度为 �n,1≤�≤1051≤n≤105),请你计算对于所有 �S 的非空子串 ��⋯�(0≤�≤�<�)Sij(0≤ij<n),�(��⋯�)f(Sij) 的和是多少。

输入描述

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

输出描述

输出一个整数表示答案。

输入输出样例

示例
输入
ababc
输出
21

运行限制

  • 最大运行时间:1s

  • 最大运行内存: 256M

题目分析:

题目给出了一个字符串,找出子串中一个字符出现一次的总个数。这道题刚看的时候想直接用暴力把他干掉。暴力思路就是直接套两层for循环,外循环代表着子串的有边界,内循环代表着子串的左边界。然后我们取出这个子串,我们在去找里面只出现一次的字符,然后我们把他们全部加起来就是最后结果。但是这个嘞会超时,只能拿到40分,不过在比赛的时候,如果想不到优化,这样子就可以,直接来一手骗分。优化的思路呢: 算出每个字符做出的贡献,先一层循环i,然后 在用两根指针right,left,left向左遍历,right向右遍历,当s[left]==s[i] 就退出向左和向右的遍历,然后这个相对应的字符做出的贡献就是(left+1)*(right+1),然后每个字符做出的贡献全部相加,就是结果了

AC代码:


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in) ;
        String s = scanner.next();

        char[] chars = s.toCharArray();

        int len = chars.length ;
        int res= 0 ;
        for(int  i =0 ;i<len;i++){
            int left =0 ;
            int right = 0 ;
            char c = chars[i];
            for (int  j = i-1 ; j>=0 && chars[j]!=c;j--){
                left++ ;
            }

            for (int k = i+1 ; k<len&& chars[k]!=c ; k++){
                right++ ;
            }

            res += (left+1)*(right+1) ;
        }


        System.out.println(res);

        scanner.close(); 


    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

little Chen1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值