Java 查找具有指定数量的奇数整数的子阵列数

Java 查找具有指定数量的奇数整数的子阵列数,java,arrays,algorithm,Java,Arrays,Algorithm,给定一个整数数组和一个整数m,如何找到包含m个奇数整数的所有子数组?下面是一个完整的问题,如果我的不够长的描述。有没有比n^2更快的解决方案?我下面的解决方案似乎是n^2,我不确定如何进一步优化它 静态长数组(int[]a,int m){ 整数和=0; for(int i=0;i

给定一个整数数组和一个整数m,如何找到包含m个奇数整数的所有子数组?下面是一个完整的问题,如果我的不够长的描述。有没有比n^2更快的解决方案?我下面的解决方案似乎是n^2,我不确定如何进一步优化它

静态长数组(int[]a,int m){
整数和=0;
for(int i=0;i
考虑了一个算法,但没有机会验证其复杂性(我认为应该是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


通过对每个最小子数组的展开形式数求和,可以得到所需的结果。

这是双指针方法的任务

制作两个索引-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


指针只遍历数组一次,复杂性是线性的。

我在任何地方都找不到足够的解释来解释这个问题,所以我已经尽了最大努力一步一步地解释这个问题

下面是这个问题的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;
}
步骤1:

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

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

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

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

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。

import java.util.HashSet;
import java.util.HashSet;

public class subarray {

    public static void main(String[] args) {
        //        int numbers[] = {1, 2, 3, 4};
        //        int numbers[] = {6, 3, 5, 8};
        //        int kk = 1;
        int numbers[] = {2, 1, 2, 1, 3};
        int kk = 2;
        HashSet<Integer> evenElements = new HashSet<>();
        HashSet<Integer> oddElements = new HashSet<>();
        int count = 0;
        for (int i = 0; i < numbers.length; i++) {
            if (numbers[i] % 2 == 0) {
                evenElements.add(numbers[i]);
            } else {
                oddElements.add(numbers[i]);
            }
        }
        for (int i = 0; i < numbers.length; i++) {
            for (int j = i + 1; j < numbers.length; j++) {
                int odd = 0;
                for (int k = i; k <= j; k++) {
                    boolean flag = true;
                    for (int l = 0; l < i; l++) {
                        if (numbers[l] == numbers[i] && numbers[l + 1] == numbers[j]) {
                            flag = false;
                        }
                    }
                    if (flag) {
                        if (numbers[k] % 2 != 0) {
                            odd = odd + 1;
                        }
                    }
                }
                if (odd != 0 && odd <= kk) {
                    count = count + 1;
                }
            }
        }
        System.out.println(count + oddElements.size() + evenElements.size());
    }
}
公共类子阵{ 公共静态void main(字符串[]args){ //整数[]={1,2,3,4}; //整数[]={6,3,5,8}; //int kk=1; 整数[]={2,1,2,1,3}; int kk=2; HashSet=newhashset(); HashSet oddElements=新HashSet(); 整数计数=0; for(int i=0;inoOfOddNumbersSoFar = 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
import java.util.HashSet;

public class subarray {

    public static void main(String[] args) {
        //        int numbers[] = {1, 2, 3, 4};
        //        int numbers[] = {6, 3, 5, 8};
        //        int kk = 1;
        int numbers[] = {2, 1, 2, 1, 3};
        int kk = 2;
        HashSet<Integer> evenElements = new HashSet<>();
        HashSet<Integer> oddElements = new HashSet<>();
        int count = 0;
        for (int i = 0; i < numbers.length; i++) {
            if (numbers[i] % 2 == 0) {
                evenElements.add(numbers[i]);
            } else {
                oddElements.add(numbers[i]);
            }
        }
        for (int i = 0; i < numbers.length; i++) {
            for (int j = i + 1; j < numbers.length; j++) {
                int odd = 0;
                for (int k = i; k <= j; k++) {
                    boolean flag = true;
                    for (int l = 0; l < i; l++) {
                        if (numbers[l] == numbers[i] && numbers[l + 1] == numbers[j]) {
                            flag = false;
                        }
                    }
                    if (flag) {
                        if (numbers[k] % 2 != 0) {
                            odd = odd + 1;
                        }
                    }
                }
                if (odd != 0 && odd <= kk) {
                    count = count + 1;
                }
            }
        }
        System.out.println(count + oddElements.size() + evenElements.size());
    }
}