一个算法题目 给定一个数组其每个元素都是正数,和一个给定值M,求所有连续的子数组其和可以整除M

给定一个数组其每个元素都是正数,和一个给定值M,求所有连续的子数组其和可以整除M请给出思路。补充一下不能用双层循环。。... 给定一个数组其每个元素都是正数,和一个给定值M,求所有连续的子数组其和可以整除M
请给出思路。
补充一下 不能用双层循环。。
展开
 我来答
匿名用户
2013-10-24
展开全部

假设数组为a,有n个元素。
假设prefix[i]是a数组的前i个元素的和,令prefix[0] = 0。
如果prefix[j]%M == prefix[i]%M(其中0 <= j < i <= n),则a[j+1 ~ i]的和能被M整除。
于是对于每个i,可以用个表之类的数据结构快速找出它之前有多少个prefix[j]%M和prefix[i]%M相等,每次查找和更新的复杂度大约是O(1)的。
如果M比较小的话可以直接开个数组存之前prefix[j]%M出现了几次,复杂度是O(n + M)的。
如果M比较大,可以用二叉树或者哈希表存之前出现的prefix[j]%M出现了几次,因为这个值最多有O(n)种可能性,复杂度分别是O(n*log(n))和O(n)的。
如果需要记录有那些连续子数组,只要在表里记录一下有那些j就行了。

/* O(n + M)的算法 */
int work(vector<int> a, int M) {
    vector<int> b(M, 0);
    b[0] = 1;
    int prefix = 0, ans = 0;
    for (vector<int>::iterator it = a.begin(); it != a.end(); ++it) {
        prefix = (prefix + *it) % M;
        ans += b[prefix];
        b[prefix] += 1;
    }
    return ans;
}
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式