📌  相关文章
📜  在执行查询以将 (i – L + 1) 添加到范围 [L, R] 中的每个元素后打印修改后的数组

📅  最后修改于: 2021-09-06 05:59:30             🧑  作者: Mango

给定一个由N 0 s(基于 1 的索引)和另一个数组query []组成的数组arr[] ,每行的形式为{L, R} ,每个查询(L, R)的任务是添加一个(i – L + 1)[L, R]范围内的值并打印执行所有查询后获得的数组arr[]

例子:

朴素方法:解决给定问题的最简单方法是在范围[L, R]上遍历给定数组,并将值(i – L + 1) 添加到每个查询范围内的每个元素。完成所有查询后,打印得到的修改后的数组arr[]

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to perform the given queries
// in the given empty array of size N
void updateQuery(vector > queries,
                 int N)
{
    // Initialize an array a[]
    vector a(N + 1, 0);
 
    // Stores the size of the array
    int n = N + 1;
 
    int q = queries.size();
 
    // Traverse the queries
    for (int i = 0; i < q; i++) {
 
        // Starting index
        int l = queries[i][0];
 
        // Ending index
        int r = queries[i][1];
 
        // Increment each index from L to
        // R in a[] by (j - l + 1)
        for (int j = l; j <= r; j++) {
            a[j] += (j - l + 1);
        }
    }
 
    // Print the modified array
    for (int i = 1; i <= N; i++) {
        cout << a[i] << " ";
    }
}
 
// Driver Code
int main()
{
    int N = 7;
    vector > queries
        = { { 1, 7 }, { 3, 6 }, { 4, 5 } };
 
    // Function Call
    updateQuery(queries, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to perform the given queries
// in the given empty array of size N
static void updateQuery(int [][]queries, int N)
{
     
    // Initialize an array a[]
    ArrayList a = new ArrayList();
    for(int i = 0; i < N + 1; i++)
        a.add(0);
 
    // Stores the size of the array
    int q = 3;
 
    // Traverse the queries
    for(int i = 0; i < q; i++)
    {
         
        // Starting index
        int l = queries[i][0];
 
        // Ending index
        int r = queries[i][1];
 
        // Increment each index from L to
        // R in a[] by (j - l + 1)
        for(int j = l; j <= r; j++)
        {
            a.set(j, a.get(j)+(j - l + 1));
        }
    }
 
    // Print the modified array
    for(int i = 1; i < a.size(); i++)
    {
        System.out.print(a.get(i) + " ");
    }
}
 
// Driver code
public static void main(String[] args)
{
    int N = 7;
    int[][] queries =  { { 1, 7 },
                         { 3, 6 },
                         { 4, 5 } };
                                  
    // Function Call
    updateQuery(queries, N);
}
}
 
// This code is contributed by offbeat


Python3
# Python 3 program for the above approach
 
# Function to perform the given queries
# in the given empty array of size N
def updateQuery(queries, N):
   
    # Initialize an array a[]
    a = [0 for i in range(N + 1)]
 
    # Stores the size of the array
    n = N + 1
 
    q = len(queries)
 
    # Traverse the queries
    for i in range(q):
       
        # Starting index
        l = queries[i][0]
 
        # Ending index
        r = queries[i][1]
 
        # Increment each index from L to
        # R in a[] by (j - l + 1)
        for j in range(l, r + 1, 1):
            a[j] += (j - l + 1)
 
    # Print the modified array
    for i in range(1, N + 1, 1):
        print(a[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
    N = 7
    queries =  [[1, 7],[3, 6],[4, 5]]
 
    # Function Call
    updateQuery(queries, N)
 
    # This code is contributed by ipg2016107.


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
   
// Function to perform the given queries
// in the given empty array of size N
static void updateQuery(int [,]queries, int N)
{
     
    // Initialize an array a[]
    List a = new List();
    for(int i = 0; i < N + 1; i++)
        a.Add(0);
 
    // Stores the size of the array
    int q = 3;
 
    // Traverse the queries
    for(int i = 0; i < q; i++)
    {
         
        // Starting index
        int l = queries[i, 0];
 
        // Ending index
        int r = queries[i, 1];
 
        // Increment each index from L to
        // R in a[] by (j - l + 1)
        for(int j = l; j <= r; j++)
        {
            a[j] += (j - l + 1);
        }
    }
 
    // Print the modified array
    for(int i = 1; i < a.Count; i++)
    {
        Console.Write(a[i] + " ");
    }
}
 
// Driver Code
public static void Main()
{
    int N = 7;
    int[,] queries = new int[3, 2] { { 1, 7 },
                                     { 3, 6 },
                                     { 4, 5 } };
                                      
    // Function Call
    updateQuery(queries, N);
}
}
 
// This code is contributed by SURENDRA_GANGWAR


C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to perform the given queries
// in the given empty array of size N
void updateQuery(vector > queries,
                 int N)
{
    // Stores the resultant array
    // and the difference array
    vector ans(N + 2, 0),
        res(N + 2, 0);
 
    int q = queries.size();
 
    // Traverse the given queries
    for (int i = 0; i < q; i++) {
 
        // Starting index
        int l = queries[i][0];
 
        // Ending index
        int r = queries[i][1];
 
        // Increment l-th index by 1
        ans[l]++;
 
        // Decrease r-th index by 1
        ans[r + 1]--;
 
        // Decrease (r + 1)th index by
        // the length of each query
        res[r + 1] -= (r - l + 1);
    }
 
    // Find the prefix sum of ans[]
    for (int i = 1; i <= N; i++)
        ans[i] += ans[i - 1];
 
    // Find the final array
    for (int i = 1; i <= N; i++)
        res[i] += res[i - 1] + ans[i];
 
    // Printing the modified array
    for (int i = 1; i <= N; i++) {
        cout << res[i] << " ";
    }
    cout << "\n";
}
 
// Driver Code
int main()
{
    int N = 7;
    vector > queries
        = { { 1, 7 }, { 3, 6 }, { 4, 5 } };
 
    updateQuery(queries, N);
 
    return 0;
}


输出:
1 2 4 7 10 10 7

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

高效的方法:可以通过使用前缀和来优化上述方法。请按照以下步骤解决此问题:

  • 初始化一个所有元素为0的数组ans[]以存储当前索引受查询影响的次数。
  • 初始化一个数组res[] ,所有元素都为0来存储到达某个查询范围结束后要删除的值。
  • 遍历给定的查询数组query[]并执行以下步骤:
    • 将 1 添加到ans[query[i][0]]并从ans[query[i][1] + 1] 中减去1
    • res[query[i][1] + 1] 中减去(query[i][1] – query[i][0] + 1)
  • 找到数组ans[]的前缀和。
  • 遍历数组res[]并将每个元素res[i]更新为res[i] + res[i – 1] + ans[i]
  • 完成上述步骤后,执行给定的查询后,将数组res[]打印为修改后的数组。

下面是上述方法的实现:

C++

// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to perform the given queries
// in the given empty array of size N
void updateQuery(vector > queries,
                 int N)
{
    // Stores the resultant array
    // and the difference array
    vector ans(N + 2, 0),
        res(N + 2, 0);
 
    int q = queries.size();
 
    // Traverse the given queries
    for (int i = 0; i < q; i++) {
 
        // Starting index
        int l = queries[i][0];
 
        // Ending index
        int r = queries[i][1];
 
        // Increment l-th index by 1
        ans[l]++;
 
        // Decrease r-th index by 1
        ans[r + 1]--;
 
        // Decrease (r + 1)th index by
        // the length of each query
        res[r + 1] -= (r - l + 1);
    }
 
    // Find the prefix sum of ans[]
    for (int i = 1; i <= N; i++)
        ans[i] += ans[i - 1];
 
    // Find the final array
    for (int i = 1; i <= N; i++)
        res[i] += res[i - 1] + ans[i];
 
    // Printing the modified array
    for (int i = 1; i <= N; i++) {
        cout << res[i] << " ";
    }
    cout << "\n";
}
 
// Driver Code
int main()
{
    int N = 7;
    vector > queries
        = { { 1, 7 }, { 3, 6 }, { 4, 5 } };
 
    updateQuery(queries, N);
 
    return 0;
}
输出:
1 2 4 7 10 10 7

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live