欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 14:14:39
...

给你一个整数数组 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));
 }
}

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

相关标签: 算法题目