天天看點

統計[優美子數組](力扣)

給你一個整數數組 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));
 }
}
           

代碼主要借鑒了别人了代碼,然後了解後加上了自己的了解