查询以查找没有更新的相似相邻元素的最长子序列
给定一个由N个整数组成的数组arr[]和一个数组Queries[][] ,每个查询的形式为{x, y} 。对于每个查询,任务是将索引x处的元素(基于 1 的索引)替换为y ,并找到没有相似相邻元素的最长子序列的长度。
例子:
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
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)