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

• Last Updated : 11 Jul, 2022

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```

Related Topic: Segment Tree

My Personal Notes arrow_drop_up