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:
- Add the element to the subsequence only if it is not equal to the previous element of the subsequence.
- For each query {x, y}, replace the element at index x with y.
- Keep track of the longest subsequence found at any point by a variable count.
- 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.
- After iterating the sequence once, count contains the length of longest required subsequence.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void longestSubsequence( int N, int Q,
int arr[],
int Queries[][2])
{
for ( int i = 0; i < Q; i++) {
int x = Queries[i][0];
int y = Queries[i][1];
arr[x - 1] = y;
int count = 1;
for ( int j = 1; j < N; j++) {
if (arr[j] != arr[j - 1]) {
count += 1;
}
}
cout << count << ' ' ;
}
}
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 } };
longestSubsequence(N, Q, arr, Queries);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void longestSubsequence( int N, int Q,
int arr[],
int Queries[][])
{
for ( int i = 0 ; i < Q; i++)
{
int x = Queries[i][ 0 ];
int y = Queries[i][ 1 ];
arr[x - 1 ] = y;
int count = 1 ;
for ( int j = 1 ; j < N; j++)
{
if (arr[j] != arr[j - 1 ])
{
count += 1 ;
}
}
System.out.print(count + " " );
}
}
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 } };
longestSubsequence(N, Q, arr, Queries);
}
}
|
Python3
def longestSubsequence(N, Q, arr, Queries):
for i in range (Q):
x = Queries[i][ 0 ]
y = Queries[i][ 1 ]
arr[x - 1 ] = y
count = 1
for j in range ( 1 , N):
if (arr[j] ! = arr[j - 1 ]):
count + = 1
print (count, end = ' ' )
if __name__ = = "__main__" :
arr = [ 1 , 1 , 2 , 5 , 2 ]
N = len (arr)
Q = 2
Queries = [ [ 1 , 3 ], [ 4 , 2 ] ]
longestSubsequence(N, Q, arr, Queries)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void longestSubsequence( int N, int Q,
int []arr,
int [,]Queries)
{
for ( int i = 0; i < Q; i++)
{
int x = Queries[i, 0];
int y = Queries[i, 1];
arr[x - 1] = y;
int count = 1;
for ( int j = 1; j < N; j++)
{
if (arr[j] != arr[j - 1])
{
count += 1;
}
}
Console.Write(count + " " );
}
}
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 } };
longestSubsequence(N, Q, arr, Queries);
}
}
|
Javascript
<script>
function longestSubsequence(N, Q,
arr, Queries)
{
for (let i = 0; i < Q; i++)
{
let x = Queries[i][0];
let y = Queries[i][1];
arr[x - 1] = y;
let count = 1;
for (let j = 1; j < N; j++)
{
if (arr[j] != arr[j - 1])
{
count += 1;
}
}
document.write(count + " " );
}
}
let arr = [ 1, 1, 2, 5, 2 ];
let N = arr.length;
let Q = 2;
let Queries = [[ 1, 3 ], [ 4, 2 ]];
longestSubsequence(N, Q, arr, Queries);
</script>
|
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:
- Replacing the element at index x will only affect the contribution of elements at indices x and x + 1, in the final answer.
- Therefore, subtracting the contributions of these 2 indices from the variable count and recalculating contributions of these 2 indices will give the required answer in constant time.
Follow the steps below to solve the problem:
- Initialize a variable, say count, to store the count of subsequences.
- Traverse the given array and count those elements that are different from the previous element of the array and store it in a variable count.
- Now traverse each query {x, y} and perform the following:
- If the element at index (x – 1) is different from the element at index x, then decrement count by 1.
- If the element at index (x – 1) is different from the element y, then increment count by 1.
- Similarly, if the element at index (x + 1) is different from the element at index x, then decrement count by 1.
- If the element at index (x + 1) is different from the element y, then increment count by 1.
- Print the value of count after each query as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void longestSubsequence( int N, int Q,
int arr[],
int Queries[][2])
{
int count = 1;
for ( int i = 1; i < N; i++) {
if (arr[i] != arr[i - 1]) {
count += 1;
}
}
for ( int i = 0; i < Q; i++) {
int x = Queries[i][0];
int y = Queries[i][1];
if (x > 1) {
if (arr[x - 1] != arr[x - 2]) {
count -= 1;
}
if (arr[x - 2] != y) {
count += 1;
}
}
if (x < N) {
if (arr[x] != arr[x - 1]) {
count -= 1;
}
if (y != arr[x]) {
count += 1;
}
}
cout << count << ' ' ;
arr[x - 1] = y;
}
}
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 } };
longestSubsequence(N, Q, arr, Queries);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void longestSubsequence( int N, int Q,
int arr[],
int Queries[][])
{
int count = 1 ;
for ( int i = 1 ; i < N; i++)
{
if (arr[i] != arr[i - 1 ])
{
count += 1 ;
}
}
for ( int i = 0 ; i < Q; i++)
{
int x = Queries[i][ 0 ];
int y = Queries[i][ 1 ];
if (x > 1 )
{
if (arr[x - 1 ] != arr[x - 2 ])
{
count -= 1 ;
}
if (arr[x - 2 ] != y)
{
count += 1 ;
}
}
if (x < N)
{
if (arr[x] != arr[x - 1 ])
{
count -= 1 ;
}
if (y != arr[x])
{
count += 1 ;
}
}
System.out.print(count + " " );
arr[x - 1 ] = y;
}
}
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 } };
longestSubsequence(N, Q, arr, Queries);
}
}
|
Python3
def longestSubsequence(N, Q, arr, Queries):
count = 1
for i in range ( 1 , N):
if (arr[i] ! = arr[i - 1 ]):
count + = 1
for i in range (Q):
x = Queries[i][ 0 ]
y = Queries[i][ 1 ]
if (x > 1 ):
if (arr[x - 1 ] ! = arr[x - 2 ]):
count - = 1
if (arr[x - 2 ] ! = y):
count + = 1
if (x < N):
if (arr[x] ! = arr[x - 1 ]):
count - = 1
if (y ! = arr[x]):
count + = 1
print (count, end = ' ' )
arr[x - 1 ] = y
if __name__ = = "__main__" :
arr = [ 1 , 1 , 2 , 5 , 2 ]
N = len (arr)
Q = 2
Queries = [ [ 1 , 3 ], [ 4 , 2 ] ]
longestSubsequence(N, Q, arr, Queries)
|
C#
using System;
class GFG{
static void longestSubsequence( int N, int Q,
int []arr,
int [,]Queries)
{
int count = 1;
for ( int i = 1; i < N; i++)
{
if (arr[i] != arr[i - 1])
{
count += 1;
}
}
for ( int i = 0; i < Q; i++)
{
int x = Queries[i, 0];
int y = Queries[i, 1];
if (x > 1)
{
if (arr[x - 1] != arr[x - 2])
{
count -= 1;
}
if (arr[x - 2] != y)
{
count += 1;
}
}
if (x < N)
{
if (arr[x] != arr[x - 1])
{
count -= 1;
}
if (y != arr[x])
{
count += 1;
}
}
Console.Write(count + " " );
arr[x - 1] = y;
}
}
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 } };
longestSubsequence(N, Q, arr, Queries);
}
}
|
Javascript
<script>
function longestSubsequence( N , Q , arr , Queries) {
var count = 1;
for ( var i = 1; i < N; i++) {
if (arr[i] != arr[i - 1]) {
count += 1;
}
}
for ( var i = 0; i < Q; i++) {
var x = Queries[i][0];
var y = Queries[i][1];
if (x > 1) {
if (arr[x - 1] != arr[x - 2]) {
count -= 1;
}
if (arr[x - 2] != y) {
count += 1;
}
}
if (x < N) {
if (arr[x] != arr[x - 1]) {
count -= 1;
}
if (y != arr[x]) {
count += 1;
}
}
document.write(count + " " );
arr[x - 1] = y;
}
}
var arr = [ 1, 1, 2, 5, 2 ];
var N = arr.length;
var Q = 2;
var Queries = [ [ 1, 3 ], [ 4, 2 ] ];
longestSubsequence(N, Q, arr, Queries);
</script>
|
Time Complexity: O(N + Q)
Auxiliary Space: O(N)
Last Updated :
20 Oct, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...