天天看点

统计[优美子数组](力扣)

给你一个整数数组 nums 和一个整数 k。

如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。

请返回这个数组中「优美子数组」的数目。

统计[优美子数组](力扣)

该题最开始我想到用动态规划来写的,写的时候突然想到二位数组,所以时间复杂度会达到O(n^2),所以肯定会出现超时的问题,所以对于该题要使用O(n)复杂度的算法,看了别人的题解发现他们大多是用双指针的方法做的,但是还是没想到咋写,看了别人的代码,才清楚。

该题主要用双指针记录k个奇数的右边界,然后判断左边有几个偶数,然后在进行找右边的偶数个数,每遇见一个就可以在答案上加上左边的偶数个数(这个规律看别人代码才知道的)一直进行判断,直到右指针到达边界为止

代码:

import java.math.BigInteger;
import java.util.*;
public class Main{
 public static int numberOfSubarrays(int[] nums, int k) {
  if(nums==null||nums.length==0||nums.length<k)return 0;
  int left=0,right=0;//双指针
  int count=0;//连续子数组中奇数的个数
  int res=0;//记录结果
  int preEven=0;//记录第一个奇数面前的偶数个数
  while(right<nums.length) {//连续子数组中的奇数个数
   if(count<k) {
    if(nums[right]%2!=0)count++;
    right++;
   }
   //连续子数组中奇数的个数,看第一个奇数前面有多少个偶数
   if(count==k) {
    preEven=0;
    while(count==k) {
     res++;//加上本身比如“121”这样的
     if(nums[left]%2!=0) {//退出该奇数范围,
      count--;
     }
     left++;
     preEven++;
    }
   }else {
    res+=preEven;//每次遇到right的时候就进行累加 * 后面的偶数个数---------right每增加一个就会又没数组就会增加左边的偶数的个数个  即:preEvent
   }
  }
  return res;
 }
 public static void main(String[] args) {
  Scanner sc=new Scanner(System.in);
  int n=sc.nextInt();
  int nums[]=new int [n];
  for(int i=0;i<n;i++) {
   nums[i]=sc.nextInt();
  }
  int k=sc.nextInt();
  System.out.println(numberOfSubarrays(nums,k));
 }
}
           

代码主要借鉴了别人了代码,然后理解后加上了自己的理解