📌  相关文章
📜  Q 查询的给定范围内两个 1 之间的最大 0 计数 |套装 – 2

📅  最后修改于: 2022-05-13 01:56:04.260000             🧑  作者: Mango

Q 查询的给定范围内两个 1 之间的最大 0 计数 |套装 – 2

给定一个大小为N的二进制字符串S和一个由M对形式为{L, R}的查询组成的二维数组Q[][] ,每个查询的任务是找到位于两个1之间的0的最大数量在[L, R]范围内。
例子

方法:在这个问题的 Set1 中已经讨论了另一种变体。跟踪两个实体:1 的位置和出现在任何特定位置之前的 1 的数量。使用一个集合来存储 1 的位置,并使用一个数组来存储答案。现在要在 [i,j] 范围内找到答案,请使用以下观察:

下面是上述方法的实现:

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)