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

前端之家收集整理的这篇文章主要介绍了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).是否有任何方法来优化此代码

  1. int main() {
  2. int n,*a,count1=0,m,*dp;
  3. cin>>n;
  4. a = new int[n];
  5. dp =new int[n];
  6.  
  7. for(int i=0; i<n; i++) {
  8. cin >> a[i];
  9. }
  10.  
  11. cin >> m;
  12.  
  13. for(int i=0; i<n; i++){
  14. if(a[i]%2==1) {
  15. count1++;
  16. }
  17.  
  18. dp[i] =count1;
  19. }
  20.  
  21. int prev;
  22. long count=0;
  23.  
  24. for(int i=0; i<n; i++) {
  25. prev= i==0 ? 0:dp[i-1];
  26. for(int j=i; j<n; j++) {
  27. if((dp[j] - prev) == m){
  28. count++;
  29. }
  30.  
  31. if(dp[j] - prev > m){
  32. break;
  33. }
  34. }
  35. }
  36. cout<<count;
  37. }

解决方法

这可以在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&C++相关文章