# Maximum distance between two 1s in a Binary Array in a given range

Given a binary array of size N and a range in [l, r], the task is to find the maximum distance between two 1s in this given range.

Examples:

Input: arr = {1, 0, 0, 1}, l = 0, r = 3
Output: 3
In the given range from 0 to 3, first 1 lies at index 0 and last at index 3.
Hence, maximum distance = 3 – 0 = 3.

Input: arr = {1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0}, l = 3, r = 9
Output: 6

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: We will create a segment tree to solve this.

1. Each node in the segment tree will have the index of leftmost 1 as well as rightmost 1 and an integer containing the maximum distance between any elements with value 1 in a subarray {l, r}.
2. Now, in this segment tree we can merge left and right nodes as below:
• If left node is not valid, return right node.
• If right node is not valid, return left node.
• A node is valid iff it contains at least one 0, or at least one 1.
• If both left and right nodes are valid then:
Let,

• l1 = leftmost index of 1 (-1 if 0 doesn’t exist in that interval)
• r1 = rightmost index of 1 (-1 if 0 doesn’t exist in that interval)
• max1 = maximum distance between two 1’s

then,

• Value of max1 in merged node will be maximum of maximum of value of max1 in left and right node, and difference between rightmost index of 1 in right node and leftmost index of 1 in left node.
• Value of l1 in merged node will be l1 of left node if it is not -1, else l1 of right node.
• Value of r1 in merged node will be r1 of right node if it is not -1, else r1 of left node.
3. Then, finally to find the answer we just need to call query function for the given range {l, r}.

Below is the implementation of the above approach:

## C++

 `// C++ program to find the maximum ` `// distance between two elements ` `// with value 1 within a subarray (l, r) ` ` `  `#include ` `using` `namespace` `std; ` ` `  `// Structure for each node ` `// in the segment tree ` `struct` `node { ` `    ``int` `l1, r1; ` `    ``int` `max1; ` `} seg; ` ` `  `// A utility function for ` `// merging two nodes ` `node task(node l, node r) ` `{ ` `    ``node x; ` ` `  `    ``x.l1 = (l.l1 != -1) ? l.l1 : r.l1; ` `    ``x.r1 = (r.r1 != -1) ? r.r1 : l.r1; ` `    ``x.max1 = max(l.max1, r.max1); ` ` `  `    ``if` `(l.l1 != -1 && r.r1 != -1) ` `        ``x.max1 = max(x.max1, r.r1 - l.l1); ` ` `  `    ``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] == 1) { ` `            ``seg[ind].l1 = seg[ind].r1 = qs; ` `            ``seg[ind].max1 = INT_MIN; ` `        ``} ` `        ``else` `{ ` `            ``seg[ind].l1 = seg[ind].r1 = -1; ` `            ``seg[ind].max1 = INT_MIN; ` `        ``} ` ` `  `        ``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.l1 = x.r1 = -1; ` `    ``x.max1 = INT_MIN; ` ` `  `    ``// 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); ` `    ``int` `l = 3, r = 9; ` ` `  `    ``// Build the segment tree ` `    ``build(0, n - 1, 1, arr); ` ` `  `    ``// Query in range 3 to 9 ` `    ``node ans = query(l, r, 0, n - 1, 1); ` `    ``cout << ans.max1 << ``"\n"``; ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program to find the maximum ` `// distance between two elements ` `// with value 1 within a subarray (l, r) ` `import` `java.util.*; ` ` `  `class` `GFG{ ` `  `  `// Structure for each node ` `// in the segment tree ` `static` `class` `node { ` `    ``int` `l1, r1; ` `    ``int` `max1; ` `} ` `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.l1 = (l.l1 != -``1``) ? l.l1 : r.l1; ` `    ``x.r1 = (r.r1 != -``1``) ? r.r1 : l.r1; ` `    ``x.max1 = Math.max(l.max1, r.max1); ` `  `  `    ``if` `(l.l1 != -``1` `&& r.r1 != -``1``) ` `        ``x.max1 = Math.max(x.max1, r.r1 - l.l1); ` `  `  `    ``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] == ``1``) { ` `            ``seg[ind].l1 = seg[ind].r1 = qs; ` `            ``seg[ind].max1 = Integer.MIN_VALUE; ` `        ``} ` `        ``else` `{ ` `            ``seg[ind].l1 = seg[ind].r1 = -``1``; ` `            ``seg[ind].max1 = Integer.MIN_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.l1 = x.r1 = -``1``; ` `    ``x.max1 = Integer.MIN_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; ` `    ``int` `l = ``3``, r = ``9``; ` `  `  `    ``// Build the segment tree ` `    ``build(``0``, n - ``1``, ``1``, arr); ` `  `  `    ``// Query in range 3 to 9 ` `    ``node ans = query(l, r, ``0``, n - ``1``, ``1``); ` `    ``System.out.print(ans.max1+ ``"\n"``); ` `  `  `} ` `} ` ` `  `// This code is contributed by Rajput-Ji `

## C#

 `// C# program to find the maximum ` `// distance between two elements ` `// with value 1 within a subarray (l, r) ` `using` `System; ` ` `  `class` `GFG{ ` `   `  `// Structure for each node ` `// in the segment tree ` `class` `node { ` `    ``public` `int` `l1, r1; ` `    ``public` `int` `max1; ` `} ` `static` `node []seg = ``new` `node; ` `   `  `// A utility function for ` `// merging two nodes ` `static` `node task(node l, node r) ` `{ ` `    ``node x = ``new` `node(); ` `   `  `    ``x.l1 = (l.l1 != -1) ? l.l1 : r.l1; ` `    ``x.r1 = (r.r1 != -1) ? r.r1 : l.r1; ` `    ``x.max1 = Math.Max(l.max1, r.max1); ` `   `  `    ``if` `(l.l1 != -1 && r.r1 != -1) ` `        ``x.max1 = Math.Max(x.max1, r.r1 - l.l1); ` `   `  `    ``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] == 1) { ` `            ``seg[ind].l1 = seg[ind].r1 = qs; ` `            ``seg[ind].max1 = ``int``.MinValue; ` `        ``} ` `        ``else` `{ ` `            ``seg[ind].l1 = seg[ind].r1 = -1; ` `            ``seg[ind].max1 = ``int``.MinValue; ` `        ``} ` `   `  `        ``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.l1 = x.r1 = -1; ` `    ``x.max1 = ``int``.MinValue; ` `   `  `    ``// 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; ` `    ``int` `l = 3, r = 9; ` `   `  `    ``// Build the segment tree ` `    ``build(0, n - 1, 1, arr); ` `   `  `    ``// Query in range 3 to 9 ` `    ``node ans = query(l, r, 0, n - 1, 1); ` `    ``Console.Write(ans.max1+ ``"\n"``); ` `} ` `} ` `  `  `// This code is contributed by Princi Singh `

Output:

```6
```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : Rajput-Ji, princi singh

Article Tags :
Practice Tags :

1

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.