腾讯测试开发面试题

唉,今天面试腾讯的测试开发工程师,脸被打肿了,下来查阅资料,把一道面试题讲一讲吧,题目是:
【O(N)求一个数字串能整除3的连续子串的个数,前缀和数组+对3取余组合数找规律】

例如14533254 这个字符串,如果要求只能在O(N)的时间,那么只能遍历有一重循环,而且根据以前小学学的能被3整除的数的规律,所有数字加起来能被3整除,所以利用这个来计算。

思路就是求依次将各位数字相加,得到一个数组,接着上面的14533254 这个字符串,则该数组就是{1,5,10,13,16,18,23,27},然后每位数对应莫3,就变成了{1,2,1,1,1,0,2,0}; 求出sum0(余数为0 的个数)=2, sum1(余数为1 的个数)=4, sum2(余数为2 的个数)=2,计算结果就是res=sum0+C(sum0,2)+C(sum1,2)+C(sum2,2);
其中C(sum0,2)就是一个组合数的问题,我们就以C(sum1,2)为例来说明一下

C(sum1,2)的意思就是冲sum1个数里面任意选择两个{1,145,1453,14533},选出两个从左到右去除相同的,身下的部分肯定能被3整除;
代码如下:

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;
int main()
{
	string str;
	while (cin >> str)
	{
		int len = str.length();
		
		int sum = 0;
		int sum0 = 0, sum1 = 0, sum2 = 0;
		for (int i = 0; i < len; i++)
		{
			sum += str[i] - '0';
			
			if (sum%3== 0)
				sum0++;
			else
				if (sum % 3 == 1)
					sum1++;
				else
					sum2++;
		}
		
		cout << "结果是:"<<sum0 + sum0 * (sum0 - 1) / 2 + sum1 * (sum1 - 1) / 2 + sum2 * (sum2 - 1) / 2 << endl;
	}
	return 0;
}

参考:https://www.cnblogs.com/zhazhaacmer/p/9441372.html

猜你喜欢

转载自blog.csdn.net/qq_41841073/article/details/82889982