蓝桥杯每日一更002之字串分值

原题

题目描述
对于一个字符串S,我们定义S的分值fs为s中恰好出现一次的字符个数,例如f(aba)=1,f(abc)=3,f(aaa)=0。现在给定一个字符串S0-n-1,请你计算对于所有S的非空子串的和是多少。
输入描述
输入一行包含一个由小写字母组成的字符串 S
输出描述
输出一个整数表示答案
输入输出样例
输入
ababc
输出
21

分析

  1. 举个栗子:
    在这里插入图片描述

  2. 暴力遍历,会超时

  3. 不会超时的方法: 考虑每个字符串最多能贡献几分
    思路代码都特别简单让我们来看看哈
    在这里插入图片描述

要点:

  1. 对输入的字符串的头尾进行补充,为了统一处理,同时也是判断终止的字符。
  2. 考虑每一个字符的贡献分数,以第一个字符为例,左右移动,每移动一格加一分,截止条件为:遇到下一个a,或者遇到终止字符。
  3. 字符左边得分为左移动次数,字符右边得分为右移动次数,本字符贡献得分为左右相乘

代码+注释

s = input()
# 对输入的字符串的头尾进行补充,为了统一处理。
# 0是判断终止的字符,同时保证了序号和索引的统一,第一个字符对应的索引就是1
s = "0" + s + "0"
length = len(s)


def find(i):
    # 左下标为当前位置左移一个
    left = i - 1
    # 右下标为当前位置右移一个
    right = i + 1
    # 遇到下一个相同字符,或者遇到终止字符就停止,没遇到就继续移动
    while left != 0 and s[left] != s[i]:
        left -= 1
    # 计算左得分公式为当前遍历对象下标-左下标
    left_score = i - left
    while right != length - 1 and s[right] != s[i]:
        right += 1
    # 计算右得分公式为右下标-当前遍历对象下标
    right_score = right - i

    # 当前遍历对象得分为左得分乘以右得分
    score = left_score * right_score
    return score


# 从第一个字符开始遍历到倒数第二个,倒数第一是补充的0
# 对每一个被遍历对象执行查找分数操作
# 对所有对象的分数转为列表并求和
print(sum([find(i) for i in range(1, length - 1)]))

付费咨询

微信:x15511371025
QQ:1142926171

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cv夏一笑

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

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

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

打赏作者

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

抵扣说明:

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

余额充值