Open In App

Queries to find longest subsequence having no similar adjacent elements with updates

Given an array arr[] consisting of N integers and an array Queries[][] with each query of the form {x, y}. For each query, the task is to replace the element at index x ( 1-based indexing ) by y and find the length of the longest subsequence having no similar adjacent elements.

Examples:



Input: arr[] = {1, 1, 2, 5, 2}, Q = 2, Queries[][] = {{1, 3}, {4, 2}}
Output: 5 3
Explanation:
Initially the array is {1, 1, 2, 5, 2}.
Query 1: Modifying the value at index 1 to 3, the array modifies to {3, 1, 2, 5, 2}. 
Therefore, the longest subsequence having no similar adjacent elements is {3, 1, 2, 5, 2}, which is of length 5. 
Therefore, print 5 as the answer.
Query 2: Modifying the value at index 4 to 2, the array modifies to {3, 1, 2, 2, 2}.
Now Therefore, the longest subsequence having no similar adjacent elements is {3, 1, 2}, which is of length 3.
Therefore, print 2 as the answer.

Input: arr[] = {1, 1, 2, 5, 2}, Q = 1, Queries[][] = {{2, 2}}
Output: 4
Explanation:
Initially the array is {1, 1, 2, 5, 2}.
Query 1: Modifying the value at index 2 to 2, the array modified to {1, 2, 2, 5, 2}.
Therefore, the longest subsequence having no similar adjacent elements is {1, 2, 5, 2}, which is of length 4.
Therefore, print the value as 4.



Naive Approach: Follow the steps below to solve the problem using the simplest possible approach:

  1. Add the element to the subsequence only if it is not equal to the previous element of the subsequence.
  2. For each query {x, y}, replace the element at index x with y.
  3. Keep track of the longest subsequence found at any point by a variable count.
  4. Traverse through the array and increment count variable by 1 whenever the current element of the sequence is not equal to the previous element of the sequence.
  5. After iterating the sequence once, count contains the length of longest required subsequence.

Below is the implementation of the above approach:




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the length of the
// longest subsequence such that no
// two adjacent elements are equal
void longestSubsequence(int N, int Q,
                        int arr[],
                        int Queries[][2])
{
    for (int i = 0; i < Q; i++) {
 
        // Replace element at
        // index x with y
        int x = Queries[i][0];
        int y = Queries[i][1];
 
        // Since x is 1-indexed,
        // decrement x by 1
        arr[x - 1] = y;
 
        // Keep track of number of
        // elements in subsequence
        int count = 1;
 
        for (int j = 1; j < N; j++) {
 
            // If previous element is not
            // same as current element
            if (arr[j] != arr[j - 1]) {
                count += 1;
            }
        }
 
        // Print the desired count
        cout << count << ' ';
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 1, 2, 5, 2 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int Q = 2;
    int Queries[Q][2] = { { 1, 3 }, { 4, 2 } };
 
    // Function Call
    longestSubsequence(N, Q, arr, Queries);
 
    return 0;
}




// Java program for the above approach
import java.util.*;
 
class GFG
{
 
// Function to find the length of the
// longest subsequence such that no
// two adjacent elements are equal
static void longestSubsequence(int N, int Q,
                        int arr[],
                        int Queries[][])
{
    for (int i = 0; i < Q; i++)
    {
 
        // Replace element at
        // index x with y
        int x = Queries[i][0];
        int y = Queries[i][1];
 
        // Since x is 1-indexed,
        // decrement x by 1
        arr[x - 1] = y;
 
        // Keep track of number of
        // elements in subsequence
        int count = 1;
 
        for (int j = 1; j < N; j++)
        {
 
            // If previous element is not
            // same as current element
            if (arr[j] != arr[j - 1])
            {
                count += 1;
            }
        }
 
        // Print the desired count
        System.out.print(count +" ");
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 1, 2, 5, 2 };
    int N = arr.length;
    int Q = 2;
    int Queries[][] = { { 1, 3 }, { 4, 2 } };
 
    // Function Call
    longestSubsequence(N, Q, arr, Queries);
}
}
 
// This code is contributed by gauravrajput1




# Python3 program for the above approach
 
# Function to find the length of the
# longest subsequence such that no
# two adjacent elements are equal
def longestSubsequence(N, Q, arr, Queries):
     
    for i in range(Q):
         
        # Replace element at
        # index x with y
        x = Queries[i][0]
        y = Queries[i][1]
         
        # Since x is 1-indexed,
        # decrement x by 1
        arr[x - 1] = y
 
        # Keep track of number of
        # elements in subsequence
        count = 1
 
        for j in range(1, N):
             
            # If previous element is not
            # same as current element
            if (arr[j] != arr[j - 1]):
                count += 1
 
        # Print the desired count
        print(count, end = ' ')
 
# Driver Code
if __name__ == "__main__":
 
    arr = [ 1, 1, 2, 5, 2 ]
    N = len(arr)
    Q = 2
    Queries = [ [ 1, 3 ], [ 4, 2 ] ]
 
    # Function Call
    longestSubsequence(N, Q, arr, Queries)
 
# This code is contributed by chitranayal




// C# program for
// the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find the length of the
// longest subsequence such that no
// two adjacent elements are equal
static void longestSubsequence(int N, int Q,
                               int []arr,
                               int [,]Queries)
{
    for(int i = 0; i < Q; i++)
    {
         
        // Replace element at
        // index x with y
        int x = Queries[i, 0];
        int y = Queries[i, 1];
         
        // Since x is 1-indexed,
        // decrement x by 1
        arr[x - 1] = y;
 
        // Keep track of number of
        // elements in subsequence
        int count = 1;
 
        for(int j = 1; j < N; j++)
        {
             
            // If previous element is not
            // same as current element
            if (arr[j] != arr[j - 1])
            {
                count += 1;
            }
        }
 
        // Print the desired count
        Console.Write(count +" ");
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 1, 1, 2, 5, 2 };
    int N = arr.Length;
    int Q = 2;
    int[,]Queries = { { 1, 3 }, { 4, 2 } };
     
    // Function Call
    longestSubsequence(N, Q, arr, Queries);
}
}
 
// This code is contributed by jana_sayantan




<script>
 
// JavaScript implementation of the above approach
 
// Function to find the length of the
// longest subsequence such that no
// two adjacent elements are equal
function longestSubsequence(N, Q,
                        arr, Queries)
{
    for (let i = 0; i < Q; i++)
    {
  
        // Replace element at
        // index x with y
        let x = Queries[i][0];
        let y = Queries[i][1];
  
        // Since x is 1-indexed,
        // decrement x by 1
        arr[x - 1] = y;
  
        // Keep track of number of
        // elements in subsequence
        let count = 1;
  
        for (let j = 1; j < N; j++)
        {
  
            // If previous element is not
            // same as current element
            if (arr[j] != arr[j - 1])
            {
                count += 1;
            }
        }
  
        // Print the desired count
        document.write(count +" ");
    }
}
 
// Driver code
         
    let arr = [ 1, 1, 2, 5, 2 ];
    let N = arr.length;
    let Q = 2;
    let Queries = [[ 1, 3 ], [ 4, 2 ]];
  
    // Function Call
    longestSubsequence(N, Q, arr, Queries);
  
 // This code is contributed by code_hunt.
</script>

Output: 
5 3

 

Time Complexity: O(N*Q)
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, an observation is found that the presence of an element in the required subsequence only depends on its previous element as shown below:

Follow the steps below to solve the problem:

Below is the implementation of the above approach:




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
void longestSubsequence(int N, int Q,
                        int arr[],
                        int Queries[][2])
{
    int count = 1;
 
    // Traverse the array arr[]
    for (int i = 1; i < N; i++) {
 
        // If previous element is not
        // same as current element
        if (arr[i] != arr[i - 1]) {
            count += 1;
        }
    }
 
    // Traverse the queries
    for (int i = 0; i < Q; i++) {
 
        // Replace element at
        // index x with y
        int x = Queries[i][0];
        int y = Queries[i][1];
 
        // Recalculate for index x
        if (x > 1) {
 
            // Subtract contribution
            // of element at index x
            if (arr[x - 1] != arr[x - 2]) {
                count -= 1;
            }
 
            // Add contribution of y
            if (arr[x - 2] != y) {
                count += 1;
            }
        }
 
        // Recalculate for index x + 1
        if (x < N) {
 
            // Subtract contribution of
            // element at index x + 1
            if (arr[x] != arr[x - 1]) {
                count -= 1;
            }
 
            // Adds contribution of y
            if (y != arr[x]) {
                count += 1;
            }
        }
        cout << count << ' ';
 
        // Replace the element
        arr[x - 1] = y;
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 1, 2, 5, 2 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int Q = 2;
    int Queries[Q][2] = { { 1, 3 }, { 4, 2 } };
 
    // Function Call
    longestSubsequence(N, Q, arr, Queries);
 
    return 0;
}




// Java program for the above approach
import java.util.*;
 
class GFG{
     
static void longestSubsequence(int N, int Q,
                               int arr[],
                               int Queries[][])
{
    int count = 1;
 
    // Traverse the array arr[]
    for(int i = 1; i < N; i++)
    {
         
        // If previous element is not
        // same as current element
        if (arr[i] != arr[i - 1])
        {
            count += 1;
        }
    }
     
    // Traverse the queries
    for(int i = 0; i < Q; i++)
    {
         
        // Replace element at
        // index x with y
        int x = Queries[i][0];
        int y = Queries[i][1];
 
        // Recalculate for index x
        if (x > 1)
        {
             
            // Subtract contribution
            // of element at index x
            if (arr[x - 1] != arr[x - 2])
            {
                count -= 1;
            }
 
            // Add contribution of y
            if (arr[x - 2] != y)
            {
                count += 1;
            }
        }
         
        // Recalculate for index x + 1
        if (x < N)
        {
             
            // Subtract contribution of
            // element at index x + 1
            if (arr[x] != arr[x - 1])
            {
                count -= 1;
            }
 
            // Adds contribution of y
            if (y != arr[x])
            {
                count += 1;
            }
        }
        System.out.print(count + " ");
 
        // Replace the element
        arr[x - 1] = y;
    }
}
 
// Driver Code
public static void main(String args[])
{
    int arr[] = { 1, 1, 2, 5, 2 };
    int N = arr.length;
    int Q = 2;
    int Queries[][] = { { 1, 3 }, { 4, 2 } };
 
    // Function Call
    longestSubsequence(N, Q, arr, Queries);
}
}
 
// This code is contributed by jana_sayantan




# Python3 program for the above approach
def longestSubsequence(N, Q, arr, Queries):
 
    count = 1
 
    # Traverse the array arr[]
    for i in range(1, N):
 
        # If previous element is not
        # same as current element
        if (arr[i] != arr[i - 1]):
            count += 1
             
    # Traverse the queries
    for i in range(Q):
 
        # Replace element at
        # index x with y
        x = Queries[i][0]
        y = Queries[i][1]
 
        # Recalculate for index x
        if (x > 1):
 
            # Subtract contribution
            # of element at index x
            if (arr[x - 1] != arr[x - 2]):
                count -= 1
 
            # Add contribution of y
            if (arr[x - 2] != y):
                count += 1
 
        # Recalculate for index x + 1
        if (x < N):
 
            # Subtract contribution of
            # element at index x + 1
            if (arr[x] != arr[x - 1]):
                count -= 1
 
            # Adds contribution of y
            if (y != arr[x]):
                count += 1
    
        print(count, end = ' ')
 
        # Replace the element
        arr[x - 1] = y
 
# Driver Code
if __name__ == "__main__" :
 
    arr = [ 1, 1, 2, 5, 2 ]
    N = len(arr)
    Q = 2
    Queries = [ [ 1, 3 ], [ 4, 2 ] ]
 
    # Function Call
    longestSubsequence(N, Q, arr, Queries)
 
# This code is contributed by AnkThon




// C# program for the above approach
using System;
 
class GFG{
     
static void longestSubsequence(int N, int Q,
                               int []arr,
                               int [,]Queries)
{
    int count = 1;
     
    // Traverse the array arr[]
    for(int i = 1; i < N; i++)
    {
         
        // If previous element is not
        // same as current element
        if (arr[i] != arr[i - 1])
        {
            count += 1;
        }
    }
     
    // Traverse the queries
    for(int i = 0; i < Q; i++)
    {
         
        // Replace element at
        // index x with y
        int x = Queries[i, 0];
        int y = Queries[i, 1];
 
        // Recalculate for index x
        if (x > 1)
        {
             
            // Subtract contribution
            // of element at index x
            if (arr[x - 1] != arr[x - 2])
            {
                count -= 1;
            }
 
            // Add contribution of y
            if (arr[x - 2] != y)
            {
                count += 1;
            }
        }
         
        // Recalculate for index x + 1
        if (x < N)
        {
             
            // Subtract contribution of
            // element at index x + 1
            if (arr[x] != arr[x - 1])
            {
                count -= 1;
            }
 
            // Adds contribution of y
            if (y != arr[x])
            {
                count += 1;
            }
        }
        Console.Write(count + " ");
 
        // Replace the element
        arr[x - 1] = y;
    }
}
 
// Driver Code
public static void Main(string []args)
{
    int []arr = { 1, 1, 2, 5, 2 };
    int N = arr.Length;
    int Q = 2;
    int [,]Queries = { { 1, 3 }, { 4, 2 } };
 
    // Function Call
    longestSubsequence(N, Q, arr, Queries);
}
}
 
// This code is contributed by AnkThon




<script>
 
// javascript program for the above approach
 
    function longestSubsequence( N , Q , arr , Queries) {
        var count = 1;
 
        // Traverse the array arr
        for (var i = 1; i < N; i++) {
 
            // If previous element is not
            // same as current element
            if (arr[i] != arr[i - 1]) {
                count += 1;
            }
        }
 
        // Traverse the queries
        for (var i = 0; i < Q; i++) {
 
            // Replace element at
            // index x with y
            var x = Queries[i][0];
            var y = Queries[i][1];
 
            // Recalculate for index x
            if (x > 1) {
 
                // Subtract contribution
                // of element at index x
                if (arr[x - 1] != arr[x - 2]) {
                    count -= 1;
                }
 
                // Add contribution of y
                if (arr[x - 2] != y) {
                    count += 1;
                }
            }
 
            // Recalculate for index x + 1
            if (x < N) {
 
                // Subtract contribution of
                // element at index x + 1
                if (arr[x] != arr[x - 1]) {
                    count -= 1;
                }
 
                // Adds contribution of y
                if (y != arr[x]) {
                    count += 1;
                }
            }
            document.write(count + " ");
 
            // Replace the element
            arr[x - 1] = y;
        }
    }
 
    // Driver Code
     
        var arr = [ 1, 1, 2, 5, 2 ];
        var N = arr.length;
        var Q = 2;
        var Queries = [ [ 1, 3 ], [ 4, 2 ] ];
 
        // Function Call
        longestSubsequence(N, Q, arr, Queries);
 
// This code contributed by Princi Singh
</script>

Output: 
5 3

 

Time Complexity: O(N + Q)
Auxiliary Space: O(N)


Article Tags :