La subsecuencia más larga que tiene mayores valores de esquina

Dada una array arr[] que contiene una permutación aleatoria de los primeros N números naturales, la tarea es encontrar la subsecuencia más larga que tenga la propiedad de que el primero y el último elemento son mayores que todos los demás elementos de la subsecuencia.
Ejemplos: 
 

Entrada: arr[] = {3, 1, 5, 2, 4} 
Salida:
La subsecuencia es {3, 1, 2, 4}. Los elementos de esquina de esta subsecuencia son mayores que todos los demás elementos.
Entrada: arr[] = {1, 2, 3, 4, 5} 
Salida:
No podemos hacer una subsecuencia de tamaño mayor que 2. 
 

Enfoque: si fijamos los elementos más a la izquierda y más a la derecha de una subsecuencia, nos interesa contar cuántos elementos entre ellos tienen un valor menor que ambos. Una implementación sencilla de esta idea tiene una complejidad de O(N 3 ). 
Para reducir la complejidad, abordamos el problema de manera diferente. En lugar de fijar los extremos de la subsecuencia, fijamos los elementos intermedios. La idea es que para una X dada (1 ≤ X ≤ N), queremos encontrar dos elementos mayores o iguales a X, que tengan entre ellos tantos elementos como sea posible menores que X. Para una X fija es óptimo elegir el elementos más a la izquierda y más a la derecha ≤ X. Ahora tenemos una mejor solución  O(N 2 ).
A medida que X aumenta, el elemento más a la izquierda solo puede aumentar, mientras que el más a la derecha solo puede disminuir. Podemos usar un puntero para cada uno de ellos para obtener una complejidad amortizada de O(N).
A continuación se muestra la implementación del enfoque anterior: 
 

C++

// C++ implementation of the approach
#include<bits/stdc++.h>
using namespace std;
 
#define MAXN 100005
 
// Function to return the length of the
// longest required sub-sequence
int longestSubSeq(int n, int arr [])
{
    int max_length = 0;
 
    // Create a position array to find
    // where an element is present
    int pos[MAXN];
 
    for (int i = 0; i < n; i++)
        pos[arr[i] - 1] = i;
 
    int left = n, right = 0;
 
    for (int i = n - 1, num = 1; i >= 0;
                       i -= 1, num += 1)
    {
 
        // Store the minimum position
        // to the left
        left = min(left, pos[i]);
 
        // Store the maximum position to
        // the right
        right = max(right, pos[i]);
 
        // Recompute current maximum
        max_length = max(max_length,
                         right - left - num + 3);
    }
 
    // Edge case when there is a single
    // element in the sequence
    if (n == 1)
        max_length = 1;
 
    return max_length;
}
 
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << longestSubSeq(n, arr);
}
 
// This code is contributed by ihritik

Java

// Java implementation of the approach
class GFG {
 
    static int MAXN = (int)1e5 + 5;
 
    // Function to return the length of the
    // longest required sub-sequence
    static int longestSubSeq(int n, int[] arr)
    {
        int max_length = 0;
 
        // Create a position array to find
        // where an element is present
        int[] pos = new int[MAXN];
 
        for (int i = 0; i < n; i++)
            pos[arr[i] - 1] = i;
 
        int left = n, right = 0;
 
        for (int i = n - 1, num = 1; i >= 0;
                         i -= 1, num += 1) {
 
            // Store the minimum position
            // to the left
            left = Math.min(left, pos[i]);
 
            // Store the maximum position to
            // the right
            right = Math.max(right, pos[i]);
 
            // Recompute current maximum
            max_length = Math.max(max_length,
                      right - left - num + 3);
        }
 
        // Edge case when there is a single
        // element in the sequence
        if (n == 1)
            max_length = 1;
 
        return max_length;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 3, 4, 5 };
        int n = arr.length;
        System.out.println(longestSubSeq(n, arr));
    }
}

Python3

# Python3 implementation of the approach
 
MAXN = 100005
 
# Function to return the length of the
# longest required sub-sequence
def longestSubSeq(n, arr):
 
    max_length = 0
 
    # Create a position array to find
    # where an element is present
    pos = [0] * MAXN
 
    for i in range (0, n):
        pos[arr[i] - 1] = i
 
    left = n
    right = 0
    num = 1
     
    for i in range (n - 1, -1, -1) :
 
        # Store the minimum position
        # to the left
        left = min(left, pos[i])
 
        # Store the maximum position to
        # the right
        right = max(right, pos[i])
 
        # Recompute current maximum
        max_length = max(max_length,
                right - left - num + 3)
     
        num = num + 1
         
    # Edge case when there is a single
    # element in the sequence
    if (n == 1) :
        max_length = 1
 
    return max_length
 
# Driver code
arr = [ 1, 2, 3, 4, 5 ]
n = len(arr)
print(longestSubSeq(n, arr))
 
# This code is contributed by ihritik

C#

// C# implementation of the approach
using System;
 
class GFG
{
 
    static int MAXN = (int)1e5 + 5;
 
    // Function to return the length of the
    // longest required sub-sequence
    static int longestSubSeq(int n, int[] arr)
    {
        int max_length = 0;
 
        // Create a position array to find
        // where an element is present
        int[] pos = new int[MAXN];
 
        for (int i = 0; i < n; i++)
            pos[arr[i] - 1] = i;
 
        int left = n, right = 0;
 
        for (int i = n - 1, num = 1; i >= 0;
                        i -= 1, num += 1)
        {
 
            // Store the minimum position
            // to the left
            left = Math.Min(left, pos[i]);
 
            // Store the maximum position to
            // the right
            right = Math.Max(right, pos[i]);
 
            // Recompute current maximum
            max_length = Math.Max(max_length,
                    right - left - num + 3);
        }
 
        // Edge case when there is a single
        // element in the sequence
        if (n == 1)
            max_length = 1;
 
        return max_length;
    }
 
    // Driver code
    public static void Main()
    {
        int []arr = { 1, 2, 3, 4, 5 };
        int n = arr.Length;
        Console.WriteLine(longestSubSeq(n, arr));
    }
}
 
// This code is contributed by Ryuga

PHP

<?php
// PHP implementation of the approach
 
$MAXN = 100005;
 
// Function to return the length of the
// longest required sub-sequence
function longestSubSeq($n, $arr)
{
    global $MAXN;
    $max_length = 0;
 
    // Create a position array to find
    // where an element is present
    $pos = array();
 
    for ($i = 0; $i < $n; $i++)
        $pos[$arr[$i] - 1] = $i;
 
    $left = $n;
    $right = 0;
    $num = 1;
    for ($i = $n - 1; $i >= 0 ; $i--, $num++)
    {
         
        // Store the minimum position
        // to the left
        $left = min($left, $pos[$i]);
 
        // Store the maximum position to
        // the right
        $right = max($right, $pos[$i]);
 
        // Recompute current maximum
        $max_length = max($max_length,
                          $right - $left - $num + 3);
    }
     
    // Edge case when there is a single
    // element in the sequence
    if ($n == 1)
        $max_length = 1;
 
    return $max_length;
}
 
// Driver code
$arr = array(1, 2, 3, 4, 5);
$n = sizeof($arr);
echo longestSubSeq($n, $arr);
 
// This code is contributed by ihritik
?>

Javascript

<script>
 
    // JavaScript implementation of the approach
     
    let MAXN = 1e5 + 5;
   
    // Function to return the length of the
    // longest required sub-sequence
    function longestSubSeq(n, arr)
    {
        let max_length = 0;
   
        // Create a position array to find
        // where an element is present
        let pos = new Array(MAXN);
        pos.fill(0);
   
        for (let i = 0; i < n; i++)
            pos[arr[i] - 1] = i;
   
        let left = n, right = 0;
   
        for (let i = n - 1, num = 1; i >= 0;
                        i -= 1, num += 1)
        {
   
            // Store the minimum position
            // to the left
            left = Math.min(left, pos[i]);
   
            // Store the maximum position to
            // the right
            right = Math.max(right, pos[i]);
   
            // Recompute current maximum
            max_length = Math.max(max_length,
                    right - left - num + 3);
        }
   
        // Edge case when there is a single
        // element in the sequence
        if (n == 1)
            max_length = 1;
   
        return max_length;
    }
     
    let arr = [ 1, 2, 3, 4, 5 ];
    let n = arr.length;
    document.write(longestSubSeq(n, arr));
     
</script>
Producción: 

2

 

Publicación traducida automáticamente

Artículo escrito por AmanKumarSingh 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 *