给定一个由N 个整数组成的数组arr[]和一个数组Queries[][] ,每个查询的形式为{x, y} 。对于每个查询,任务是用y替换索引x (基于 1 的索引)处的元素,并找到没有相似相邻元素的最长子序列的长度。
例子:
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.
朴素的方法:按照以下步骤使用最简单的方法解决问题:
- 仅当元素不等于子序列的前一个元素时才将元素添加到子序列。
- 对于每个查询{x, y} ,将索引x处的元素替换为y 。
- 通过变量count跟踪在任何点找到的最长子序列。
- 遍历数组并在序列的当前元素不等于序列的前一个元素时将count变量增加1 。
- 迭代一次序列后, count包含所需的最长子序列的长度。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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
// 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
# 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#
// 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
Javascript
C++
// C++ program for the above approach
#include
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
// 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
# 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#
// 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
Javascript
5 3
时间复杂度: O(N*Q)
辅助空间: O(N)
高效方法:为了优化上述方法,观察发现所需子序列中元素的存在仅取决于其前一个元素,如下所示:
- 在最终答案中,替换索引x处的元素只会影响索引x和x + 1处的元素的贡献。
- 因此,从变量计数中减去这两个指标的贡献并重新计算这两个指标的贡献将在恒定时间内给出所需的答案。
请按照以下步骤解决问题:
- 初始化一个变量,比如count ,以存储子序列的计数。
- 遍历给定的数组并计算与数组的前一个元素不同的元素并将其存储在变量count 中。
- 现在遍历每个查询{x, y}并执行以下操作:
- 如果索引(x – 1)处的元素与索引x处的元素不同,则将count递减1 。
- 如果索引(x – 1)处的元素与元素y不同,则将count增加1 。
- 类似地,如果索引(x + 1)处的元素与索引x处的元素不同,则将count减1 。
- 如果索引(x + 1)处的元素与元素y不同,则将count增加1 。
- 在每次查询后打印count的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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
// 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
蟒蛇3
# 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#
// 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
Javascript
5 3
时间复杂度: O(N + Q)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。