蓝桥题解 499 子串分值 暴力 贡献法

蓝桥题解 499.子串分值

蓝桥杯题库 题目链接

暴力解法

这题很容易想到暴力解题的思路,但是只能通过一半的测试用例。暴力解法代码如下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String str = scan.next();
        int len = str.length(), ans = 0;
        for (int i = 0; i < len; i++) {
            for (int j = i; j < len; j++) {
                String tmpStr = str.substring(i, j+1);
                ans = ans + f(tmpStr);
            }
        }
        System.out.println(ans);
        scan.close();
    }

    static int f(String str) {
        int len = str.length(), sum = 0;
        int[] s = new int[26];
        for (int i = 0; i < len; i++) {
            s[str.charAt(i) - 'a']++;
        }
        for (int i = 0; i < s.length; i++) {
            if (s[i] == 1) {
                sum++;
            }
        }
        return sum;
    }
}

贡献法

贡献法就是计算每个字符对最终结果能提供的贡献值,假设有字符串: xxaxxxaxxa。字符串中共有三个a,我们尝试计算一下第二个a对结果的贡献:

因为题目要求字符只出现一次的时候才会有贡献,那么第二个a在所有的子串情况下,有贡献的那一部分就要在第一个a后面,最后一个a前面的那一部分子串。如下图:

在这里插入图片描述

那么现在只需要考虑,在子串xxxaxx的子串中有多少种情况包含这个a,显而易见有如下12种:

在这里插入图片描述

我们可以得到其中的规律是:该字符的贡献度等于 (左边的距离+1) 乘 (右边的距离+1)。其中的距离指的是该字符到下一个相同字符的下标距离。具体代码如下:

Java代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        char[] s = scan.next().toCharArray();
        int len = s.length, ans = 0;

        for (int i = 0; i < len; i++) {
            // 计算第i个字符的贡献度,l和r分别代表字符左右的边界距离
            int l = 0, r = 0;
            for (int j = i - 1; j >= 0 && s[j] != s[i]; j--) {
                l++;
            }
            for (int j = i + 1; j < len && s[j] != s[i]; j++) {
                r++;
            }
            ans = ans + (l+1) * (r+1);
        }
        System.out.println(ans);
        scan.close();
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值