📌  相关文章
📜  检查来自索引 [L, R] 的数组元素是否形成算术级数的查询

📅  最后修改于: 2021-09-17 07:36:32             🧑  作者: Mango

给定一个由N 个整数组成的数组arr[]和一个由M 个{L, R}形式的查询组成的数组Q[][2] ,每个查询的任务是检查数组元素是否在范围[L, R ] 是否形成算术级数。如果发现是真的,打印“是” 。否则,打印“否”。

例子:

朴素的方法:解决问题的最简单方法是为每个查询在范围[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 现场工作专业课程学生竞争性编程现场课程