LeetCode statistics "beautiful sub-array" prefix and Java

Related topics :

And the sub-array of K

k times interval

Title description
Give you an integer array nums and an integer k.

If there are exactly k odd numbers in a continuous sub-array, we consider this sub-array to be a "beautiful sub-array".

Please return the number of "beautiful sub-arrays" in this array.

示例 1:
输入:nums = [1,1,2,1,1], k = 3
输出:2
解释:包含 3 个奇数的子数组是 [1,1,2,1][1,2,1,1]
示例 2:
输入:nums = [2,4,6], k = 1
输出:0
解释:数列中不包含任何奇数,所以不存在优美子数组。
示例 3:
输入:nums = [2,2,2,1,2,2,1,2,2,2], k = 2
输出:16

prompt:

1 <= nums.length <= 50000
1 <= nums[i] <= 10^5
1 <= k <= nums.length

Source: LeetCode
Link: https://leetcode-cn.com/problems/count-number-of-nice-subarrays

Ideas :

1.题目要我们找的是有多少个区间包含,k个奇数,我们把前j个区间的奇
数用前缀和保存起来,若区间[i~j]中有k奇数,即可表示为sum[j]-sum[i-1]=k,
这么一来是不是就跟“和为k的子数组”一样了;

2.直接用前缀和的做法时间复杂度是O(n)2,如果想要O(n)的时间复杂度,
怎么做呢?用前缀和的做法是这样的
 	    int res=0;
        for(int j=1;j<=length;j++){
    
    
            for(int i=1;i<=j;i++){
    
    
                if(sum[j]-sum[i-1]==k){
    
    
                    res++;
                }
            }
        }
我们要从以i为右边界里找,有多少个以j为左边界的区间使得sum[j]-
sum[i-1]=k,想减掉i这重循环,要从(sum[j]-sum[i-1]=k)这个
等式来看,sum[i-1]=sum[j]-k,这样改等式可以变成(sum[j]-
(sum[j]-k)=k)这样我们就可以把i“变没”,我们只需要找到以j为右
边间的区间里,sum[j]-k出现的次数然后相加,这里可以用数组也可以
用Hashmap;

3.这里要注意的一点是hashmap或者数组要有初始值hashmap.put(0, 1),
count[0]=1,这是因为要保持哈希表的定义, key 是当前位置之前的所
有元素的和(依然是前缀和),value 是对应的个数。在遍历开始之前,
当前位置之前的所有元素为空,可以认为和是 0,对应的个数就为 1
(来自liweiwei大佬)

Code :

    public int numberOfSubarrays(int[] nums, int k) {
    
    
        int []sum=new int[nums.length+1];//前i个数字中,奇数的个数
        //[1,2,3,4,5,6,7,8]
        //[1,1,2,2,3,3,4,4]
        
        int []count=new int [100000];
        int res=0;
        count[0]=1;
        
        for(int i=1;i<=nums.length;i++){
    
    
            sum[i]+=sum[i-1];
            //判断是否为奇数
            if(nums[i-1]%2!=0)
            sum[i]+=1;

              count[sum[i]]++;
            //奇数个数开始大于K的时候才能开始,要不然sum[i]-k小于零会越界
           if(sum[i]>=k){
    
    
            res+=count[sum[i]-k];
          
           }
        }
        return res;
     }
   }

Guess you like

Origin blog.csdn.net/qq_44844588/article/details/108545431