Distancia máxima entre dos 1 en una array binaria en un rango dado

Dada una array binaria de tamaño N y un rango en [l, r] , la tarea es encontrar la distancia máxima entre dos 1 en este rango dado.
Ejemplos: 

Entrada: arr = {1, 0, 0, 1}, l = 0, r = 3 
Salida:
En el rango dado de 0 a 3, el primer 1 se encuentra en el índice 0 y el último en el índice 3. 
Por lo tanto, la distancia máxima = 3 – 0 = 3.

Entrada: arr = {1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0}, l = 3, r = 9 
Salida:

Enfoque: Crearemos un árbol de segmentos para resolver esto. 

  1. Cada Node en el árbol de segmentos tendrá el índice de 1 más a la izquierda y 1 más a la derecha y un número entero que contiene la distancia máxima entre cualquier elemento con valor 1 en un subarreglo {l, r}.
  2. Ahora, en este árbol de segmentos podemos fusionar los Nodes izquierdo y derecho como se muestra a continuación: 
    • Si el Node izquierdo no es válido, devuelva el Node derecho.
    • Si el Node derecho no es válido, devuelva el Node izquierdo.
    • Un Node es válido si contiene al menos un 0 o al menos un 1.
    • Si los Nodes izquierdo y derecho son válidos, entonces: 
      Sea, 
      • l1 = índice más a la izquierda de 1 (-1 si 0 no existe en ese intervalo)
      • r1 = índice más a la derecha de 1 (-1 si 0 no existe en ese intervalo)
      • max1 = distancia máxima entre dos 1
      • El valor de max1 en el Node fusionado será el valor máximo de max1 en el Node izquierdo y derecho, y la diferencia entre el índice más a la derecha de 1 en el Node derecho y el índice más a la izquierda de 1 en el Node izquierdo.
      • El valor de l1 en el Node fusionado será l1 del Node izquierdo si no es -1, de lo contrario l1 del Node derecho.
      • El valor de r1 en el Node fusionado será r1 del Node derecho si no es -1, de lo contrario r1 del Node izquierdo.
  3. Luego, finalmente, para encontrar la respuesta, solo necesitamos llamar a la función de consulta para el rango dado {l, r}.

A continuación se muestra la implementación del enfoque anterior: 

C++

// C++ program to find the maximum
// distance between two elements
// with value 1 within a subarray (l, r)
 
#include <bits/stdc++.h>
using namespace std;
 
// Structure for each node
// in the segment tree
struct node {
    int l1, r1;
    int max1;
} seg[100001];
 
// 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[0]);
    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

Python3

# Python3 program to find the maximum
# distance between two elements
# with value 1 within a subarray (l, r)
import sys
 
# Structure for each node
# in the segment tree
class node():
     
    def __init__(self):
         
        self.l1 = 0
        self.r1 = 0
        self.max1 = 0
         
seg = [node() for i in range(100001)]
 
# A utility function for
# merging two nodes
def task(l, r):
     
    x = node()
  
    x.l1 = l.l1 if (l.l1 != -1) else r.l1
    x.r1 = r.r1 if (r.r1 != -1)  else l.r1
  
    x.max1 = max(l.max1, r.max1)
  
    # If both the nodes are valid
    if (l.r1 != -1 and r.l1 != -1):
        x.max1 = max(x.max1, r.r1 - l.l1)
  
    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] == 1):
            seg[ind].l1 = seg[ind].r1 = qs
            seg[ind].max1 = -sys.maxsize
             
        else:
            seg[ind].l1 = seg[ind].r1 = -1
            seg[ind].max1 = -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.l1 = x.r1 = -1
    x.max1 = -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)
     
    l = 3
    r = 9
     
    # Build the segment tree
    build(0, n - 1, 1, arr)
     
    # Query in range 3 to 9
    ans = query(l, r, 0, n - 1, 1)
     
    print(ans.max1)
 
# This code is contributed by rutvik_56

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[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 = 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

Javascript

<script>
  
// JavaScript program to find the maximum
// distance between two elements
// with value 1 within a subarray (l, r)
 
// Structure for each node
// in the segment tree
class node {
    constructor()
    {
        this.l1 = 0;
        this.r1 = 0;
        this.max1 =0;
    }
}
 
var seg = Array(100001);
   
// A utility function for
// merging two nodes
function task(l, r)
{
    var 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
function build(qs, qe, ind, 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 = -1000000000;
        }
        else {
            seg[ind].l1 = seg[ind].r1 = -1;
            seg[ind].max1 = -1000000000;
        }
   
        return;
    }
    var 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
function query(qs, qe, ns, ne, ind)
{
    var x = new node();
    x.l1 = x.r1 = -1;
    x.max1 = -1000000000;
   
    // 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
    var mid = (ns + ne) >> 1;
   
    var l = query(qs, qe, ns,
                   mid, ind << 1);
    var r = query(qs, qe,
                   mid + 1, ne,
                   ind << 1 | 1);
   
    x = task(l, r);
    return x;
}
   
// Driver code
for(var i = 0; i < 100001; i++)
    seg[i] = new node();
var arr = [1, 1, 0,
              1, 0, 1,
              0, 1, 0,
              1, 0, 1,
              1, 0];
var n = arr.length;
var l = 3, r = 9;
 
// Build the segment tree
build(0, n - 1, 1, arr);
 
// Query in range 3 to 9
var ans = query(l, r, 0, n - 1, 1);
document.write(ans.max1+ "<br>");
 
 
</script>
Producción: 

6

 

Publicación traducida automáticamente

Artículo escrito por muskan_garg y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *