给定一个由N 个整数组成的数组arr[]和一个由M 个{L, R}形式的查询组成的数组Q[][2] ,每个查询的任务是检查数组元素是否在范围[L, R ] 是否形成算术级数。如果发现是真的,打印“是” 。否则,打印“否”。
例子:
Input: arr[] = {1, 3, 5, 7, 6, 5, 4, 1}, Q[][] = {{0, 3}, {3, 4}, {2, 4}}
Output:
Yes
Yes
No
Explanation:
Query 1: The elements of the array over the range [0, 3] are {1, 3, 5, 7} which forms an arithmetic series with a common difference of 2. Hence, print “Yes”.
Query 2: The elements of the array over the range [3, 4 are {7, 6} which forms an arithmetic series with a common difference of -1. Hence, print “Yes”.
Query 3: The elements of the array over the range [2, 4 are {5, 7, 6}, which does not form an arithmetic series. Hence, print “Yes”.
Input: arr[] = {1, 2}, Q[][] = {{0, 0}, {0, 1}, {0, 1}}
Output:
Yes
Yes
Yes
朴素的方法:解决问题的最简单方法是为每个查询在范围[L, R]上遍历给定数组,并检查所有相邻元素之间的公共差异是否相同。如果差异相同,则打印“是” 。否则,打印“否” 。
时间复杂度: O(N*M)
辅助空间: O(1)
高效的方法:上述方法可以基于以下观察进行优化:
- 这个想法是使用双指针算法预先计算子数组的最长长度,从任何索引i开始,对于辅助数组中的数组的每个第i个元素,比如dp[] 。
- 对于给定的范围[L, R] ,如果dp[L]的值大于或等于(R – L) ,则该范围将始终形成AP,因为(R – L)是元素的当前范围并且dp[L]存储从索引L形成 AP 的最长子阵列的长度,那么子阵列长度必须小于dp[L] 。
请按照以下步骤解决问题:
- 初始化一个数组,比如dp[]以存储从该索引处的每个元素的每个索引开始的最长子数组的长度。
- 使用变量i在范围[0, N] 上迭代并执行以下步骤:
- 将变量j初始化为(i + 1)以存储从索引i形成算术级数的最后一个索引数组。
- 递增j的值直到(j + 1 < N)并且(arr[j] – arr[j – 1])与(arr[i + 1] – arr[i]) 相同。
- 使用变量在[i, j – 1]范围内迭代,例如K ,并将dp[K]的值更新为(j – K) 。
- 将i的值更新为j 。
- 遍历给定的查询数组Q[]并且对于每个查询{L, R}如果dp[L]的值大于或等于(R – L) ,则打印“Yes” 。否则,打印“否”。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if the given range
// of queries form an AP or not in the
// given array arr[]
void findAPSequence(int arr[], int N,
int Q[][2], int M)
{
// Stores length of the longest
// subarray forming AP for every
// array element
int dp[N + 5] = { 0 };
// Iterate over the range [0, N]
for (int i = 0; i + 1 < N;) {
// Stores the index of the last
// element of forming AP
int j = i + 1;
// Iterate until the element at
// index (j, j + 1) forms AP
while (j + 1 < N
&& arr[j + 1] - arr[j]
== arr[i + 1] - arr[i])
// Increment j by 1
j++;
// Traverse the current subarray
// over the range [i, j - 1]
for (int k = i; k < j; k++) {
// Update the length of the
// longest subarray at index k
dp[k] = j - k;
}
// Update the value of i
i = j;
}
// Traverse the given queries
for (int i = 0; i < M; i++) {
// Print the result
if (dp[Q[i][0]]
>= Q[i][1] - Q[i][0]) {
cout << "Yes" << endl;
}
// Otherwise
else {
cout << "No" << endl;
}
}
}
// Driver Code
int main()
{
int arr[] = { 1, 3, 5, 7, 6, 5, 4, 1 };
int Q[][2] = { { 0, 3 }, { 3, 4 }, { 2, 4 } };
int N = sizeof(arr) / sizeof(arr[0]);
int M = sizeof(Q) / sizeof(Q[0]);
findAPSequence(arr, N, Q, M);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Function to check if the given range
// of queries form an AP or not in the
// given array arr[]
static void findAPSequence(int arr[], int N,
int Q[][], int M)
{
// Stores length of the longest
// subarray forming AP for every
// array element
int dp[] = new int[N + 5];
// Iterate over the range [0, N]
for(int i = 0; i + 1 < N;)
{
// Stores the index of the last
// element of forming AP
int j = i + 1;
// Iterate until the element at
// index (j, j + 1) forms AP
while (j + 1 < N && arr[j + 1] - arr[j] ==
arr[i + 1] - arr[i])
// Increment j by 1
j++;
// Traverse the current subarray
// over the range [i, j - 1]
for(int k = i; k < j; k++)
{
// Update the length of the
// longest subarray at index k
dp[k] = j - k;
}
// Update the value of i
i = j;
}
// Traverse the given queries
for(int i = 0; i < M; i++)
{
// Print the result
if (dp[Q[i][0]] >= Q[i][1] - Q[i][0])
{
System.out.println("Yes");
}
// Otherwise
else
{
System.out.println("No");
}
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 3, 5, 7, 6, 5, 4, 1 };
int Q[][] = { { 0, 3 }, { 3, 4 }, { 2, 4 } };
int N = arr.length;
int M = Q.length;
findAPSequence(arr, N, Q, M);
}
}
// This code is contributed by Kingash
Python3
# Python3 program for the above approach
# Function to check if the given range
# of queries form an AP or not in the
# given array arr[]
def findAPSequence(arr, N, Q, M):
# Stores length of the longest
# subarray forming AP for every
# array element
dp = [0] * (N + 5)
# Iterate over the range [0, N]
i = 0
while i + 1 < N:
# Stores the index of the last
# element of forming AP
j = i + 1
# Iterate until the element at
# index (j, j + 1) forms AP
while (j + 1 < N and
arr[j + 1] - arr[j] ==
arr[i + 1] - arr[i]):
# Increment j by 1
j += 1
# Traverse the current subarray
# over the range [i, j - 1]
for k in range(i, j):
# Update the length of the
# longest subarray at index k
dp[k] = j - k
# Update the value of i
i = j
# Traverse the given queries
for i in range(M):
# Print the result
if (dp[Q[i][0]] >= Q[i][1] - Q[i][0]):
print("Yes")
# Otherwise
else:
print("No")
# Driver Code
if __name__ == "__main__":
arr = [ 1, 3, 5, 7, 6, 5, 4, 1 ]
Q = [ [ 0, 3 ], [ 3, 4 ], [ 2, 4 ] ]
N = len(arr)
M = len(Q)
findAPSequence(arr, N, Q, M)
# This code is contributed by ukasp
C#
// C# code for above approach
using System;
public class GFG
{
// Function to check if the given range
// of queries form an AP or not in the
// given array arr[]
static void findAPSequence(int[] arr, int N,
int[, ] Q, int M)
{
// Stores length of the longest
// subarray forming AP for every
// array element
int[] dp = new int[N + 5];
// Iterate over the range [0, N]
for(int i = 0; i + 1 < N;)
{
// Stores the index of the last
// element of forming AP
int j = i + 1;
// Iterate until the element at
// index (j, j + 1) forms AP
while (j + 1 < N && arr[j + 1] - arr[j] ==
arr[i + 1] - arr[i])
// Increment j by 1
j++;
// Traverse the current subarray
// over the range [i, j - 1]
for(int k = i; k < j; k++)
{
// Update the length of the
// longest subarray at index k
dp[k] = j - k;
}
// Update the value of i
i = j;
}
// Traverse the given queries
for(int i = 0; i < M; i++)
{
// Print the result
if (dp[Q[i, 0]] >= Q[i, 1] - Q[i, 0])
{
Console.WriteLine("Yes");
}
// Otherwise
else
{
Console.WriteLine("No");
}
}
}
static public void Main (){
int[] arr = { 1, 3, 5, 7, 6, 5, 4, 1 };
int[, ] Q = { { 0, 3 }, { 3, 4 }, { 2, 4 } };
int N = arr.Length;
int M = Q.GetLength(0);
findAPSequence(arr, N, Q, M);
}
}
// This code is contributed by offbeat
Javascript
Yes
Yes
No
时间复杂度: O(N + M)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。