牛客(美团)- 字符串计数(动态规划)

题目描述

求字典序在s1和s2之间的,长度在len1到len2的字符串的个数,结果mod 1000007。

输入描述:
每组数据包涵s1(长度小于100),s2(长度小于100),len1(小于100000),len2(大于len1,小于100000)
输出描述:
输出答案。

示例1
输入
ab ce 1 2
输出
56

解释
字典序:从两个字符串的下标为0开始进行对比,字典序是从左往右进行对比的

例如ab,abc这样两者之间的字符串有aba、abb,而ab、bb两者之间的字符串有ac、ad、ae……az、ba这25个(这里规定长度为2),如果再包括长度为1的,则还有一个b也在范围内。

其次,所谓的长度在len1到len2的字符串个数,指的是长度在len1的字符串个数、长度在len1 + 1 …… 长度在len2的字符串个数。这是闭区间,len1,len2两头的情况也要考虑。

例如abcde、acede,如果要求其长度在1到4之间的字符串,那就是要找到a和a两个字符串之间的字符串个数(长度为1)ab和ac两个字符串之间的字符串个数(长度为2时),abc和ace之间的字符串个数(长度为3时)以及abcd和aced之间的(长度为4时)

思路

1、用上动态规划的思想,首先从长度为1开始,计算出此长度之下两个字符串之间有多少个字符串;然后通过长度为1拥有的字符串额数量计算出长度为2时……直到长度为len2
2、计算后需要最后相加才能得到最终值,相加的时候判断一下就行,当计算长度达到len1时便可开始进行叠加操作了。

代码

import java.util.Scanner;

public class StrCount {

	public static void main(String[] args) 
	{
		Scanner input = new Scanner(System.in);
		
		while (input.hasNext()) 
		{
			String str1 = input.next();
			String str2 = input.next();

			int len1 = input.nextInt();
			int len2 = input.nextInt();
			
			// 获取两个字符串长度
			char[] ch1 = str1.toCharArray();
			char[] ch2 = str2.toCharArray();
			
			int resNum = 0;
			// 定义一个长度为len2+1的数组,用于保存每个长度下两个字符串之间的字符串数
			int[] dp = new int[len2 + 1];
			// 从长度为1开始循环到len2结束,这里dp数组是从下标为1开始存储对应长度的字符数
			for (int i = 1; i <= len2; i++) 
			{	// 每个长度下拥有的字符串个数为上一个长度下字符串个数乘以26(不是最终结果,后面还有加减操作)
				dp[i] = (dp[i - 1] * 26) % 1000007;
				// 如果长度没有超过str1,那么需要减去str1这一位置上的那个字符与96的差值(该值表示在范围之外的个数,也就是*26那步操作多计算进去的几个)
				if (i <= str1.length()) dp[i] = dp[i] - (ch1[i - 1] - 96);
				// 如果长度没有超过str2,那么需要加上str2这一位置上的哪个字符与96的差值(该值表示还有几个是上述*26没有算上了)
				if (i <= str2.length()) dp[i] = dp[i] + (ch2[i - 1] - 96);

				if (i >= len1) resNum += dp[i];
			}
			// 最后结束叠加时,需要-1,因为最后的长度下需要减去str2最后一个字符的自身情况
			System.out.println((resNum - 1) % 1000007);
		}
		input.close();
	}
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值