Q 查询的给定范围内两个 1 之间的最大 0 计数 |套装 – 2
给定一个大小为N的二进制字符串S和一个由M对形式为{L, R}的查询组成的二维数组Q[][] ,每个查询的任务是找到位于两个1之间的0的最大数量在[L, R]范围内。
例子:
Input: S = “1001010”, Q[][] = {{0, 4}, {0, 5}}
Output: 2 3
Explanation:
The Queries are performed as per the following:
- Query(0, 4): Print 2 as there are maximum 2 0’s lying between the indices 0 and 3 in the substring over the range [0, 4] i.e., “10010”.
- Query(0, 5): Print 3 as there are maximum 3 0’s lying between the indices 0 and 5 in the substring over the range [0, 5] i.e., “100101”.
Input: S = “101”, Q[][] = {{0, 2}}
Output: 1
方法:在这个问题的 Set1 中已经讨论了另一种变体。跟踪两个实体:1 的位置和出现在任何特定位置之前的 1 的数量。使用一个集合来存储 1 的位置,并使用一个数组来存储答案。现在要在 [i,j] 范围内找到答案,请使用以下观察:
Let first and last 1s between given range is located at (i+first) and (i+last), then
Total 0’s between 1’s = total elements between these two locations – total 1’s between these to locations
= location difference between 1’s – (1’s appeared before (i+last) – 1’s appeared before (i+first) )
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to get the number of
// 0s between two 1s
vector
zBetweeno(string s,
vector >& queries)
{
// Store location of 1s
set ones;
// Store number of candles before i
vector one(s.size(), 0);
// Store result
vector res;
// Storing number of candles before
// a specific position
// and locations of candles in a set
for (int i = 0; i < s.size(); i++) {
if (s[i] == '1') {
ones.insert(i);
one[i]++;
}
if (i != 0)
one[i] += one[i - 1];
}
// Iterating over queries
for (auto&& query : queries) {
// Get the location of first 1
int ss
= *ones.lower_bound(query[0]);
// Get the location of last 1
int ee
= s[query[1]] == '1'
? query[1]
: *--ones.lower_bound(query[1]);
// Check for corner cases
if (ss > query[1]
|| ee < query[0]) {
res.push_back(0);
continue;
}
int tot
= one[ee] - one[ss];
int loc = ee - ss;
// Storing result of the query
res.push_back(loc
- tot);
}
return res;
}
// Driver code
int main()
{
vector > queries
= { { 0, 4 }, { 0, 5 } };
string input = "1001010";
vector res =
zBetweeno(input, queries);
for (auto elem : res)
cout << elem << " ";
cout << endl;
}
Python3
# Python 3 implementation of the above approach
from bisect import bisect_left
# Function to get the number of
# 0s between two 1s
def zBetweeno(s, queries):
# Store location of 1s
ones = set([])
# Store number of candles before i
one = [0]*len(s)
# Store result
res = []
# Storing number of candles before
# a specific position
# and locations of candles in a set
for i in range(len(s)):
if (s[i] == '1'):
ones.add(i)
one[i] += 1
if (i != 0):
one[i] += one[i - 1]
# Iterating over queries
for query in queries:
# Get the location of first 1
ss = bisect_left(list(ones), query[0])
# Get the location of last 1
if s[query[1]] == '1':
ee = query[1]
else:
ee = bisect_left(list(ones), query[1])
# Check for corner cases
if (ss > query[1]
or ee < query[0]):
res.append(0)
continue
tot = one[ee] - one[ss]
loc = ee - ss
# Storing result of the query
res.append(loc
- tot)
return res
# Driver code
if __name__ == "__main__":
queries = [[0, 4], [0, 5]]
input = "1001010"
res = zBetweeno(input, queries)
for elem in res:
print(elem, end=" ")
# This code is contributed by ukasp.
2 3
时间复杂度: O(N*logN)
辅助空间: O(N)