You are given a binary string s and an integer k.
You are also given a 2D integer array queries, where queries[i] = [li, ri].
A binary string satisfies the k-constraint if either of the following conditions holds:
0's in the string is at most k.1's in the string is at most k.Return an integer array answer, where answer[i] is the number of substrings of s[li..ri] that satisfy the k-constraint.
Example 1:
Input: s = "0001111", k = 2, queries = [[0,6]]
Output: [26]
Explanation:
For the query [0, 6], all substrings of s[0..6] = "0001111" satisfy the k-constraint except for the substrings s[0..5] = "000111" and s[0..6] = "0001111".
Example 2:
Input: s = "010101", k = 1, queries = [[0,5],[1,4],[2,3]]
Output: [15,9,3]
Explanation:
The substrings of s with a length greater than 3 do not satisfy the k-constraint.
Constraints:
1 <= s.length <= 105s[i] is either '0' or '1'.1 <= k <= s.length1 <= queries.length <= 105queries[i] == [li, ri]0 <= li <= ri < s.lengthThis approach utilizes prefix sums to quickly fetch the count of 0's and 1's within any substring specified by a query. The prefix sums are computed for zeros and ones separately. Once this preprocessing is done, each query is processed using a sliding window with the help of the prefix sums to count the valid substrings efficiently.
In the Python implementation, we first calculate the prefix sums for both zeros and ones. This allows us to find the count of zeros and ones within any given range efficiently.
For each query, we employ a two-pointer technique (sliding window) to evaluate possible substrings and count those that meet the k-constraint. We expand the right end of the window and check if the substring satisfies the k-constraint. If valid, we calculate how many substrings end with this position and then attempt to expand. We also increment the left pointer when the substring exceeds the k-constraint.
C++
Time Complexity: O(n + q × m), where n is the length of the string, q is the number of queries, and m is the average length of the queried substrings.
Space Complexity: O(n), primarily due to the prefix sums array.
This approach leverages a Binary Indexed Tree (BIT) to efficiently manage and query substring ranges. BIT is useful for dynamic cumulative sum computations, providing optimized point updates and prefix sum queries. This is more complex but beneficial for dynamic ranges where direct sum retrieval is critical.
In this Python code, we define a Fenwick Tree class to manage updates and prefix sum retrievals efficiently for both zeros and ones. We utilize two Fenwick Trees - one to track zeros and another to track ones across indices of the binary string.
For each query, we perform a nested iteration for every starting and ending position, and utilize the BIT to check if the substring is valid according to the k-constraint. This approach, while more sophisticated in its data structure, isn't as efficient as desired due to the single-loop nested within constraints. Optimizations beyond BIT may be required for high density queries.
Time Complexity: O(n log n + q × m log m), where n is the string length, q is the number of queries, and m is the average length of substrings per query.
Space Complexity: O(n), due to BIT structures for zeros and ones.
| Approach | Complexity |
|---|---|
| Approach 1: Using Prefix Sums and Sliding Window | Time Complexity: O(n + q × m), where n is the length of the string, q is the number of queries, and m is the average length of the queried substrings. |
| Approach 2: Binary Indexed Tree (Fenwick Tree) | Time Complexity: O(n log n + q × m log m), where n is the string length, q is the number of queries, and m is the average length of substrings per query. |
Count Substrings That Satisfy K-Constraint I & II | Detailed Explanation | Leetcode 3258 & 3261 • codestorywithMIK • 6,249 views views
Watch 9 more video solutions →Practice Count Substrings That Satisfy K-Constraint II with our built-in code editor and test cases.
Practice on FleetCodePractice this problem
Open in Editor