蓝桥杯每日一更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

猜你喜欢

转载自blog.csdn.net/cvxiayixiao/article/details/129945050