c – 给定一个数组找到m个奇数的子数组?

样本输入:
1 2 3 4 5(数组元素)
m = 1(奇数)
样本输出
8.
子阵列是[[1],[1,2],[2,3],3,4],[3],[3,[4,5],[5]]

这是我的实现.在最坏的情况下,它需要O(n n ^ 2).是否有任何方法来优化此代码

int main() {
    int n,*a,count1=0,m,*dp;
    cin>>n;
    a = new int[n];
    dp =new int[n];

    for(int i=0; i<n; i++) {
        cin >> a[i];
    }

    cin >> m;

    for(int i=0; i<n; i++){
        if(a[i]%2==1) {
            count1++;
        }

        dp[i] =count1;
    }

    int prev;
    long count=0;

    for(int i=0; i<n; i++) {
        prev= i==0 ? 0:dp[i-1];
        for(int j=i; j<n; j++) {
            if((dp[j] - prev) == m){
                count++;
            }

            if(dp[j] - prev > m){
                break;
            }
        }
    }
    cout<<count;
}

解决方法

这可以在O(n)中解决.首先生成奇数之间的间隙长度的数组,将两端计为隐式奇数.在这种情况下,该数组是g = [0,1,0].然后我们求和(g [i] 1)*(g [i m] 1)因为它表示有多少子阵列在第i个奇数开始或恰好在第i个奇数之前,并且在第i个奇数之后或之后结束.

在这种情况下,我们得到1 * 2 2 * 2 2 * 1 = 8.

替代解释
想想想要的子阵列.每个人都从某处开始,包括m个奇数,然后在其他地方结束.让我们根据它们包含的奇数字串将它们分成组.每个组包含一些i的第i个奇数,并且以第m-1个奇数结束.起点在第i-1和第i个奇数之间的每个偶数处,以及第i个奇数本身.这是第i个奇数1之前的间隙的大小.或者在我的计算中g(i)1.类似地,结束点位于第m-1个奇数处,或者在该第i个奇数之间的所有均匀处.这是i m-1和i mth奇数之间差距的1倍.在我的计算中,g(i m)为1.因此,该组中的数字是起点数乘以结束点数.其中(g(i)1)*(g(i m)1).在所有起点上添加我,我们得到了答案.

我掩饰了一个重要的细节.这是我假设包含奇数,所以0<米如果m = 0,则计算完全改变.然后答案是1和(g(i)*(g(i)-1)/ 2).

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...