java—查找具有指定奇数整数数的子数组数

5ktev3wc  于 2021-07-03  发布在  Java
关注(0)|答案(3)|浏览(350)

给定一个整数数组和一个整数m,如何找到包含m个奇数整数的所有子数组?下面是一个完整的问题,如果我的不够长的描述。有没有比n^2更快的解决方案?我下面的解决方案似乎是n^2,我不确定如何进一步优化它。
https://github.com/cem3394/hr-haskell/blob/master/beautifulsubarrays.hs

static long beautifulSubarrays(int[] a, int m) {
    int sum = 0;
    for (int i = 0; i < a.length; i++){
        for (int j = i, c =0; j < a.length; j++){
            if (a[j] %2 !=0){
                c++;
            }
            if ((c==m) && (z==j)){
                over = true;
                sum++;
                break
            }
            boolean over = false;
            if (over) break;
            for (int z = i, c = 0; z <= j; z++){
                if (a[z]%2 != 0){
                    c++;

                }
                if (c>m){
                    over = true;
                    break;

                }
                if ((c==m) && (z==j)){
                    over = true;
                    sum++;
                    break;
                }
            }
        }
    }
    return sum;

    }
hgqdbh6s

hgqdbh6s1#

这是双指针方法的任务。
制作两个索引-l和r。
将l设置为0,将r从0向右移动,计算od计数器中的奇数。当od变为m时,记住r位置为r0。进一步移动r,直到满足新的奇数。
记住l位置为l0,并递增l直到满足奇数(如果[l0]为奇数,则保持不变)。
现在所有子数组都从 L0..L 范围和结束于 R0..R-1 范围,正好包含m个奇数。有 Cnt = (L-L0+1) * (R-R0) 这样的子阵列:

m=3 
       L0 L        R0           R
i      0  1  2  3  4  5  6  7  8 
A[i]   4  1  3  2  5  6  2  2  3

所有从0..1开始到4..7结束的子数组都包含3个奇数,这里有2个开始索引和4个结束索引,所以 Cnt = 8 增量l,再次记住r0,重复此过程直到数组结束,为结果中设置的每个范围添加cnt
指针只遍历数组一次,复杂性是线性的。

disbfnqx

disbfnqx2#

想到了一个算法,但还没有机会验证其复杂性(我认为应该是o(n))

找出所有“最小”子数组

目的是找出以奇数开头和结尾的所有子数组。
以o(n)方式实现的一种方法是:对数组进行一次遍历,并记录所有奇数索引:
e、 g.输入 [ 2,3,4,6,7,1,10 ] ,你应该可以 [1,4,5] (索引1、4、5为奇数)
假设子数组中有两个奇数,则为 [1,4] 以及 [4,5] ###找出每个子数组的展开形式
基本思想是,对于每个最小子数组,可以包含前面的奇数和后面的奇数。
以数组[4..5]为例:

[ 2,3,4,6,7,1,10 ]
          ^ ^

您可以选择在偶数之前包含0、1或2。同时,您可以选择包含0或1个后续偶数。
也就是说,对于这个特定的子数组,有2*3=6“展开形式”
快速找到前/后偶数个数的方法很简单,只需从 [1,4,5][-1,1,4,5,7] . 索引4之前偶数的前一个数是4-1,即3,索引5之后偶数的后一个数是7-5,即2。
通过对每个最小子阵的展开形式数求和,可以得到所需的结果。

knpiaxh1

knpiaxh13#

我在任何地方都找不到足够的解释来解释这个问题,所以我尽了最大的努力一步一步地解释这个问题。
下面是这个问题的js版本,时间复杂度为o(n)。
输入:arr-要处理的数组,m-要显示的整数数
返回:奇数为m的唯一子数组的数目

function beautifulArray(arr, m) {
  var noOfOddNumbersSoFar = 0;
  var ans = 0;
  var save = []; // Save possible number of sub arrays till i with m odd numbers

  for (var i = 0; i < arr.length; i++) {
    if (save[noOfOddNumbersSoFar]) {
      save[noOfOddNumbersSoFar]++;
    } else {
      save[noOfOddNumbersSoFar] = 1;
    }

    noOfOddNumbersSoFar += arr[i] % 2 == 0 ? 0 : 1;

    if (noOfOddNumbersSoFar >= m) {
      ans += save[noOfOddNumbersSoFar - m];
    }
  }

  return ans;
}

解释我们在这里所做的是计算可以形成的子阵列的总数,直到我们达到m个奇数,并将其保存到名为save的数组中。我们只需将其添加到我们的答案中,就可以得到可以形成的子阵列的总数。我们这样做直到我们到达最后一个元素。
考虑以下输入

arr = [2,2,5,6,9,2,11];
m = 2;

第一步:

noOfOddNumbersSoFar = 0
save[noOfOddNumbersSoFar] is set to 1. i.e, save = [1]
i = 0
arr[i] is 2 (even)
noOfOddNumbersSoFar remains 0

第二步:

noOfOddNumbersSoFar = 0
save[noOfOddNumbersSoFar] is set to 2. i.e, save = [2]
i = 1
arr[i] is 2 (even)
noOfOddNumbersSoFar remains 0

第三步:

noOfOddNumbersSoFar = 0
save[noOfOddNumbersSoFar] is set to 3. i.e, save = [3]
i = 2
arr[i] is 5 (odd)
noOfOddNumbersSoFar is set to 1

第四步:

noOfOddNumbersSoFar = 1
save[noOfOddNumbersSoFar] is set to 1. i.e, save = [3, 1]
i = 3
arr[i] is 6 (even)
noOfOddNumbersSoFar remains 1

第五步:

noOfOddNumbersSoFar = 1
save[noOfOddNumbersSoFar] is set to 2. i.e, save = [3, 2]
i = 4
arr[i] is 9 (odd)
noOfOddNumbersSoFar is set to 2

noOfOddNumbersSoFar is >= m(2)
  noOfOddNumbersSoFar - m 
  So we take the number of possible subarrays from the saved variable save[0] and add it to ans. ans = 3

Here 3 denotes [2, 2, 5, 6, 9], [2, 5, 6, 9] and [5, 6, 9].

第6步:

noOfOddNumbersSoFar = 2
save[noOfOddNumbersSoFar] is set to 1. i.e, save = [3, 2, 1]
i = 5
arr[i] is 2 (even)
noOfOddNumbersSoFar remains 2

noOfOddNumbersSoFar is >= m(2)
  noOfOddNumbersSoFar - m is still 0
  So we take the number of possible subarrays from the saved variable save[0] and add it to ans. ans = 3 + 3 = 6

We are adding 3 more to the ans. It denotes three more sub arrays which can meet the condition. They are [2, 2, 5, 6, 9, 2], [2, 5, 6, 9, 2] and [5, 6, 9, 2].

We have addressed [2, 2, 5, 6, 9], [2, 5, 6, 9], [5, 6, 9], [2, 2, 5, 6, 9, 2], [2, 5, 6, 9, 2] and [5, 6, 9, 2] so far. // ans = 6

第7步:

noOfOddNumbersSoFar = 2
save[noOfOddNumbersSoFar] is set to 2. i.e, save = [3, 2, 2]
i = 6
arr[6] is 11 (odd)
noOfOddNumbersSoFar is set to 3

noOfOddNumbersSoFar is >= m(2)
noOfOddNumbersSoFar - m is still 1
So we take the number of possible subarrays from the saved variable save[1] and add it to ans. ans = 6 + 2 = 8

We are adding 2 more to the ans. It denotes two more sub arrays which can meet the condition. They are [6, 9, 2, 11] and [9, 2, 11].

We have addressed [2, 2, 5, 6, 9], [2, 5, 6, 9], [5, 6, 9], [2, 2, 5, 6, 9, 2], [2, 5, 6, 9, 2], [5, 6, 9, 2], [6, 9, 2, 11] and [9, 2, 11] so far. // ans = 8

因为没有更多的元素存在,没有更多的子数组可以满足这个条件,ans返回8。

相关问题