Related Articles

# Binary Array Range Queries to find the minimum distance between two Zeros

• Last Updated : 02 Dec, 2020

Prerequisite: Segment Trees
Given a binary array arr[] consisting of only 0’s and 1’s and a 2D array Q[][] consisting of K queries, the task is to find the minimum distance between two 0’s in the range [L, R] of the array for every query {L, R}.

Examples:

Input: arr[] = {1, 0, 0, 1}, Q[][] = {{0, 2}}
Output:
Explanation:
Clearly, in the range [0, 2], the first 0 lies at index 1 and last at index 2.
Minimum distance = 2 – 1 = 1.

Input: arr[] = {1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0}, Q[][] = {{3, 9}, {10, 13}}
Output: 2 3
Explanation:
In the range [3, 9], the minimum distance between 0’s is 2 (Index 4 and 6).
In the range [10, 13], the minimum distance between 0’s is 3 (Index 10 and 13).

Approach: The idea is to use a segment tree to solve this problem:

1. Every node in the segment tree will have the index of leftmost 0 as well as rightmost 0 and an integer containing the minimum distance between 0’s in the subarray {L, R}.
2. Let min be the minimum distance between two zeroes. Then, the value of min can be found after forming the segment tree as:
min = minimum(value of min in the left node, the value of min in the right node, and the difference between the leftmost index of 0 in right node and rightmost index of 0 in left node).
3. After computing and storing the minimum distance for every node, all the queries can be answered in logarithmic time.

Below is the implementation of the above approach:

## C++

 `// C++ program to find the minimum``// distance between two elements``// with value 0 within a subarray (l, r)` `#include ``using` `namespace` `std;` `// Structure for each node``// in the segment tree``struct` `node {``    ``int` `l0, r0;``    ``int` `min0;``} seg;` `// A utility function for``// merging two nodes``node task(node l, node r)``{``    ``node x;` `    ``x.l0 = (l.l0 != -1) ? l.l0 : r.l0;` `    ``x.r0 = (r.r0 != -1) ? r.r0 : l.r0;` `    ``x.min0 = min(l.min0, r.min0);` `    ``// If both the nodes are valid``    ``if` `(l.r0 != -1 && r.l0 != -1)` `        ``// Computing the minimum distance to store``        ``// in the segment tree``        ``x.min0 = min(x.min0, r.l0 - l.r0);` `    ``return` `x;``}` `// A recursive function that constructs``// Segment Tree for given string``void` `build(``int` `qs, ``int` `qe, ``int` `ind, ``int` `arr[])``{``    ``// If start is equal to end then``    ``// insert the array element``    ``if` `(qs == qe) {` `        ``if` `(arr[qs] == 0) {``            ``seg[ind].l0 = seg[ind].r0 = qs;``            ``seg[ind].min0 = INT_MAX;``        ``}` `        ``else` `{``            ``seg[ind].l0 = seg[ind].r0 = -1;``            ``seg[ind].min0 = INT_MAX;``        ``}` `        ``return``;``    ``}` `    ``int` `mid = (qs + qe) >> 1;` `    ``// Build the segment tree``    ``// for range qs to mid``    ``build(qs, mid, ind << 1, arr);` `    ``// Build the segment tree``    ``// for range mid+1 to qe``    ``build(mid + 1, qe, ind << 1 | 1, arr);` `    ``// Merge the two child nodes``    ``// to obtain the parent node``    ``seg[ind] = task(seg[ind << 1],``                    ``seg[ind << 1 | 1]);``}` `// Query in a range qs to qe``node query(``int` `qs, ``int` `qe, ``int` `ns, ``int` `ne, ``int` `ind)``{``    ``node x;``    ``x.l0 = x.r0 = -1;``    ``x.min0 = INT_MAX;` `    ``// If the range lies in this segment``    ``if` `(qs <= ns && qe >= ne)``        ``return` `seg[ind];` `    ``// If the range is out of the bounds``    ``// of this segment``    ``if` `(ne < qs || ns > qe || ns > ne)``        ``return` `x;` `    ``// Else query for the right and left``    ``// child node of this subtree``    ``// and merge them``    ``int` `mid = (ns + ne) >> 1;` `    ``node l = query(qs, qe, ns, mid, ind << 1);``    ``node r = query(qs, qe, mid + 1, ne, ind << 1 | 1);` `    ``x = task(l, r);``    ``return` `x;``}` `// Driver code``int` `main()``{` `    ``int` `arr[] = { 1, 1, 0, 1, 0, 1,``                ``0, 1, 0, 1, 0, 1, 1, 0 };` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);` `    ``// Build the segment tree``    ``build(0, n - 1, 1, arr);` `    ``// Queries``    ``int` `Q[] = { { 3, 9 }, { 10, 13 } };` `    ``for` `(``int` `i = 0; i < 2; i++) {` `// Finding the answer for every query``// and printing it``        ``node ans = query(Q[i], Q[i],``                        ``0, n - 1, 1);` `        ``cout << ans.min0 << endl;``    ``}` `    ``return` `0;``}`

## Java

 `// Java program to find the minimum``// distance between two elements``// with value 0 within a subarray (l, r)``class` `GFG{` `// Structure for each Node``// in the segment tree``static` `class` `Node``{``    ``int` `l0, r0;``    ``int` `min0;``};` `static` `Node[] seg = ``new` `Node[``100001``];` `// A utility function for``// merging two Nodes``static` `Node task(Node l, Node r)``{``    ``Node x = ``new` `Node();` `    ``x.l0 = (l.l0 != -``1``) ? l.l0 : r.l0;` `    ``x.r0 = (r.r0 != -``1``) ? r.r0 : l.r0;` `    ``x.min0 = Math.min(l.min0, r.min0);` `    ``// If both the Nodes are valid``    ``if` `(l.r0 != -``1` `&& r.l0 != -``1``)` `        ``// Computing the minimum distance to store``        ``// in the segment tree``        ``x.min0 = Math.min(x.min0, r.l0 - l.r0);` `    ``return` `x;``}` `// A recursive function that constructs``// Segment Tree for given string``static` `void` `build(``int` `qs, ``int` `qe,``                  ``int` `ind, ``int` `arr[])``{``    ` `    ``// If start is equal to end then``    ``// insert the array element``    ``if` `(qs == qe)``    ``{``        ``if` `(arr[qs] == ``0``)``        ``{``            ``seg[ind].l0 = seg[ind].r0 = qs;``            ``seg[ind].min0 = Integer.MAX_VALUE;``        ``}` `        ``else``        ``{``            ``seg[ind].l0 = seg[ind].r0 = -``1``;``            ``seg[ind].min0 = Integer.MAX_VALUE;``        ``}``        ``return``;``    ``}` `    ``int` `mid = (qs + qe) >> ``1``;` `    ``// Build the segment tree``    ``// for range qs to mid``    ``build(qs, mid, ind << ``1``, arr);` `    ``// Build the segment tree``    ``// for range mid+1 to qe``    ``build(mid + ``1``, qe, ind << ``1` `| ``1``, arr);` `    ``// Merge the two child Nodes``    ``// to obtain the parent Node``    ``seg[ind] = task(seg[ind << ``1``],``                    ``seg[ind << ``1` `| ``1``]);``}` `// Query in a range qs to qe``static` `Node query(``int` `qs, ``int` `qe, ``int` `ns,``                  ``int` `ne, ``int` `ind)``{``    ``Node x = ``new` `Node();``    ``x.l0 = x.r0 = -``1``;``    ``x.min0 = Integer.MAX_VALUE;` `    ``// If the range lies in this segment``    ``if` `(qs <= ns && qe >= ne)``        ``return` `seg[ind];` `    ``// If the range is out of the bounds``    ``// of this segment``    ``if` `(ne < qs || ns > qe || ns > ne)``        ``return` `x;` `    ``// Else query for the right and left``    ``// child Node of this subtree``    ``// and merge them``    ``int` `mid = (ns + ne) >> ``1``;` `    ``Node l = query(qs, qe, ns, mid,``                          ``ind << ``1``);``    ``Node r = query(qs, qe, mid + ``1``,``                  ``ne, ind << ``1` `| ``1``);` `    ``x = task(l, r);``    ``return` `x;``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``for``(``int` `i = ``0``; i < ``100001``; i++)``    ``{``        ``seg[i] = ``new` `Node();``    ``}` `    ``int` `arr[] = { ``1``, ``1``, ``0``, ``1``, ``0``, ``1``, ``0``,``                  ``1``, ``0``, ``1``, ``0``, ``1``, ``1``, ``0` `};` `    ``int` `n = arr.length;` `    ``// Build the segment tree``    ``build(``0``, n - ``1``, ``1``, arr);` `    ``// Queries``    ``int``[][] Q = { { ``3``, ``9` `}, { ``10``, ``13` `} };` `    ``for``(``int` `i = ``0``; i < ``2``; i++)``    ``{``        ` `        ``// Finding the answer for every query``        ``// and printing it``        ``Node ans = query(Q[i][``0``], Q[i][``1``],``                         ``0``, n - ``1``, ``1``);` `        ``System.out.println(ans.min0);``    ``}``}``}` `// This code is contributed by sanjeev2552`

## Python3

 `# Python3 program to find the minimum``# distance between two elements with``# value 0 within a subarray (l, r)``import` `sys`` ` `# Structure for each node``# in the segment tree``class` `node():``    ` `    ``def` `__init__(``self``):``        ` `        ``self``.l0 ``=` `0``        ``self``.r0 ``=` `0``        ``min0 ``=` `0``        ` `seg ``=` `[node() ``for` `i ``in` `range``(``100001``)]`` ` `# A utility function for``# merging two nodes``def` `task(l, r):``    ` `    ``x ``=` `node()``      ` `    ``x.l0 ``=` `l.l0 ``if` `(l.l0 !``=` `-``1``) ``else` `r.l0``    ``x.r0 ``=` `r.r0 ``if` `(r.r0 !``=` `-``1``)  ``else` `l.r0`` ` `    ``x.min0 ``=` `min``(l.min0, r.min0)`` ` `    ``# If both the nodes are valid``    ``if` `(l.r0 !``=` `-``1` `and` `r.l0 !``=` `-``1``):`` ` `        ``# Computing the minimum distance to``        ``# store in the segment tree``        ``x.min0 ``=` `min``(x.min0, r.l0 ``-` `l.r0)`` ` `    ``return` `x`` ` `# A recursive function that constructs``# Segment Tree for given string``def` `build(qs, qe, ind, arr):`` ` `    ``# If start is equal to end then``    ``# insert the array element``    ``if` `(qs ``=``=` `qe):`` ` `        ``if` `(arr[qs] ``=``=` `0``):``            ``seg[ind].l0 ``=` `seg[ind].r0 ``=` `qs``            ``seg[ind].min0 ``=` `sys.maxsize``            ` `        ``else``:``            ``seg[ind].l0 ``=` `seg[ind].r0 ``=` `-``1``            ``seg[ind].min0 ``=` `sys.maxsize`` ` `        ``return`` ` `    ``mid ``=` `(qs ``+` `qe) >> ``1``    ` `    ``# Build the segment tree``    ``# for range qs to mid``    ``build(qs, mid, ind << ``1``, arr)`` ` `    ``# Build the segment tree``    ``# for range mid+1 to qe``    ``build(mid ``+` `1``, qe, ind << ``1` `| ``1``, arr)`` ` `    ``# Merge the two child nodes``    ``# to obtain the parent node``    ``seg[ind] ``=` `task(seg[ind << ``1``],``                    ``seg[ind << ``1` `| ``1``])``                    ` `# Query in a range qs to qe``def` `query(qs, qe, ns, ne, ind):`` ` `    ``x ``=` `node()``    ``x.l0 ``=` `x.r0 ``=` `-``1``    ``x.min0 ``=` `sys.maxsize`` ` `    ``# If the range lies in this segment``    ``if` `(qs <``=` `ns ``and` `qe >``=` `ne):``        ``return` `seg[ind]`` ` `    ``# If the range is out of the bounds``    ``# of this segment``    ``if` `(ne < qs ``or` `ns > qe ``or` `ns > ne):``        ``return` `x`` ` `    ``# Else query for the right and left``    ``# child node of this subtree``    ``# and merge them``    ``mid ``=` `(ns ``+` `ne) >> ``1`` ` `    ``l ``=` `query(qs, qe, ns, mid, ind << ``1``)``    ``r ``=` `query(qs, qe, mid ``+` `1``, ne, ind << ``1` `| ``1``)`` ` `    ``x ``=` `task(l, r)``    ` `    ``return` `x` `# Driver code ``if` `__name__``=``=``"__main__"``:``    ` `    ``arr ``=` `[ ``1``, ``1``, ``0``, ``1``, ``0``, ``1``, ``0``,``            ``1``, ``0``, ``1``, ``0``, ``1``, ``1``, ``0` `]`` ` `    ``n ``=` `len``(arr)`` ` `    ``# Build the segment tree``    ``build(``0``, n ``-` `1``, ``1``, arr)``    ` `    ``# Queries``    ``Q ``=` `[ [ ``3``, ``9` `], [ ``10``, ``13` `] ]``    ` `    ``for` `i ``in` `range``(``2``):`` ` `        ``# Finding the answer for every query``        ``# and printing it``        ``ans ``=` `query(Q[i][``0``], Q[i][``1``], ``0``,``                    ``n ``-` `1``, ``1``)``        ` `        ``print``(ans.min0)` `# This code is contributed by rutvik_56`

Output:

```2
3```

My Personal Notes arrow_drop_up