Count Number of Nice Subarrays - Complete Solution Guide
Count Number of Nice Subarrays is LeetCode problem 1248, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
Given an array of integers nums and an integer k . A continuous subarray is called nice if there are k odd numbers on it. Return the number of nice sub-arrays . Example 1: Input: nums = [1,1,2,1,1], k = 3 Output: 2 Explanation: The only sub-arrays with 3 odd numbers are [1,1,2,1] and [1,2,1,1]. Example 2: Input: nums = [2,4,6], k = 1 Output: 0 Explanation: There are no odd numbers in the array. Example 3: Input: nums = [2,2,2,1,2,2,1,2,2,2], k = 2 Output: 16 Constraints: 1 <= nums.length <= 5000
Detailed Explanation
The problem asks us to find the number of "nice" subarrays within a given array of integers, `nums`. A subarray is considered "nice" if it contains exactly `k` odd numbers. We need to count and return the number of such subarrays, given the array `nums` and the integer `k`.
Solution Approach
The solution uses the principle of inclusion-exclusion to efficiently count the number of subarrays with exactly k odd numbers. It calculates the number of subarrays with at most k odd numbers and then subtracts the number of subarrays with at most k-1 odd numbers. This difference gives the exact count of subarrays with k odd numbers. The `atMost` function uses the sliding window technique. The right pointer moves to the right, including more elements in the current window. The left pointer only moves when the number of odd numbers in the current window exceeds the specified limit, effectively shrinking the window from the left to satisfy the constraint.
Step-by-Step Algorithm
- Step 1: Define a helper function `atMost(k_val)` that counts the number of subarrays with at most `k_val` odd numbers.
- Step 2: Initialize `res = 0`, `left = 0`, and `odd_count = 0`. `res` will store the count of valid subarrays, `left` is the left boundary of the sliding window, and `odd_count` tracks the number of odd numbers in the current window.
- Step 3: Iterate through the `nums` array using a `right` pointer (sliding window).
- Step 4: For each `right`, check if `nums[right]` is odd. If it is, increment `odd_count`.
- Step 5: While `odd_count > k_val`, shrink the window from the left by incrementing `left` and decrementing `odd_count` if `nums[left]` was odd.
- Step 6: The current window `[left, right]` is valid. Add the number of subarrays ending at `right` to `res`. The number of such subarrays is `right - left + 1`.
- Step 7: After the loop completes, the function returns `res`.
- Step 8: Finally, in the main function `numberOfSubarrays`, return `atMost(k) - atMost(k - 1)`.
Key Insights
- Insight 1: The core idea is to realize that counting subarrays with exactly `k` odd numbers can be done by finding the difference between the number of subarrays with *at most* `k` odd numbers and the number of subarrays with *at most* `k-1` odd numbers.
- Insight 2: The 'atMost' function efficiently counts subarrays satisfying an upper bound constraint (at most k odd numbers) using a sliding window technique.
- Insight 3: We can determine if a number is odd or even by using the modulo operator (%) efficiently, as `num % 2 == 1` implies an odd number.
Complexity Analysis
Time Complexity: O(n)
Space Complexity: O(1)
Topics
This problem involves: Array, Hash Table, Math, Sliding Window, Prefix Sum.
Companies
Asked at: Deliveroo, Roblox.