给定一个数组,打印所有可能的连续子序列,其总和可被给定数 x 整除

Posted

技术标签:

【中文标题】给定一个数组,打印所有可能的连续子序列,其总和可被给定数 x 整除【英文标题】:Given an array, print all possible contiguous subsequences whose sum is divisible by a given number x 【发布时间】:2015-11-05 02:25:40 【问题描述】:

给定一个数组,打印所有可能的连续子序列,其总和可以被给定数 x 整除。

我可以看到一些相关的问题:- [Find numbers of subarray of an array whose sum is divided by given number

[how to find the length of the longest contiguous subarray whose sum is divisible by a given number

所有人都要求打印最大数组或最大数组的长度。我想打印那些可以被给定数字整除的连续数组的所有组合。 我试图解决这个问题并想出了这个解决方案

#include<iostream>
using namespace std;

void function(int arr[], int start, int end, int div, int sum)

    if(start>end)
        return;
    if(!(sum%div))
    
        if(start<end)
        
            for(int i=start;i<=end;i++)
            
                cout<<"  "<<arr[i];
            
            cout<<endl;
        
    
    function(arr, start+1, end, div, sum-arr[start]);
    function(arr, start, end-1, div, sum-arr[end]);


int main()

    int arr[] = 2, 6, 3, 8, 5, 7, 4, 1;
    int div;
    int size = sizeof(arr)/sizeof(*arr);
    cout<<"  Enter divisor :- ";
    cin>>div;
    int sum = 0;
    for(int i=0;i<size;i++)
        sum+=arr[i];
    function(arr, 0, size-1, div, sum);

    cout<<endl;
    system("PAUSE");
    return 0;

此代码具有可怕的复杂性,我可以想到另一种解决方案,使用两个复杂度为 O(n^2) 的循环。 我们能否以比 n^2 时间复杂度更好的方式做到这一点?

【问题讨论】:

我不明白。你想要最大的数组,最大数组的长度,所有的子数组还是子数组的计数?因为如果你想要所有子数组(不仅仅是计数),没有比 O(n^2) 更好的解决方案,因为最多可以有 O(n^2) 个子数组(想想一个充满偶数和 x 的输入数组=2)。 @JuanLopes ,是的,我需要所有可能的子数组组合,满足给定条件。 所以没有比 O(n^2) 更好的解决方案,因为结果本身有 O(n^2) 项。 其实每个子数组都有O(n)个元素,没有比O(n^3)更好的算法了。 (这就是我们通常在这里切换到输出敏感边界的原因;在 O(n + s) 之间存在差异,其中 s 是输出的大小,这是可以在此处实现的,并且直接向上O(n^3))。 【参考方案1】:

我假设您已经阅读了答案 Find numbers of subarray of an array whose sum is divided by given number 。

如果是,那么您可以将上述算法修改如下:

Input:    0  5  3  8  2  1
X = 3
Sum:   0  0  5  8 16 18 19
Mod 3: 0  0  2  2  1  0  1

只要在“mod 3”输出数组中看到相同的值,您需要做的就是打印该数组。因此,在上述情况下,您将从索引 [0]、[2]、[0, 4]、[1, 4] 和 [4 ,5] 打印数组。

0  5  3  8  2  1
-                     0                 =  0 % 3 = 0
-------------         0 + 5 + 3 + 8 + 2 = 18 % 3 = 0
   ----------         5 + 3 + 8 + 2     = 18 % 3 = 0
      -               3                 =  3 % 3 = 0
            ----      2 + 1             =  3 % 3 = 0

【讨论】:

以上是关于给定一个数组,打印所有可能的连续子序列,其总和可被给定数 x 整除的主要内容,如果未能解决你的问题,请参考以下文章

数字总和可被 K 整除的子数组的数量

总和可被k整除的最长子序列[关闭]

计算总和可被 k 整除的子序列总数

给定一个数组和一个总和,找到小于总和的最大长度连续子数组

计算给定总和为零的所有连续子数组

最大连续子序列和