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

📅  最后修改于: 2021-04-17 18:10:07             🧑  作者: Mango

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

例子:

天真的方法:解决问题的最简单方法是遍历每个查询的[L,R]范围内的给定数组并检查所有相邻元素之间的公共差异是否相同。如果差异相同,则打印“是” 。否则,打印“否”

时间复杂度: O(N * M)
辅助空间: O(1)

高效的方法:可以基于以下观察来优化上述方法:

  • 这个想法是使用双指针算法,针对辅助阵列中每个阵列的i元素dp [],从任何索引i开始预先计算形成AP的子阵列的最长长度。
  • 对于给定的范围[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 (arr [j] – arr [j – 1])(arr [i + 1] – arr [i])相同。
    • 使用变量K遍历[i,j – 1]范围,并将dp [K]的值更新为(j – K)
    • i的值更新为j
  • 遍历给定的查询Q []数组,并且对于每个查询{L,R},如果dp [L]的值大于或等于(R – L) ,则打印“是” 。否则,打印“否”。

下面是上述方法的实现:

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


输出:
Yes
Yes
No

时间复杂度: O(N + M)
辅助空间: O(N)