给定由N 0 s组成的数组arr []和形式为(L,R)的每一行的数组Q [] [] ,每个查询的任务是更新[L, R] ,使得arr [i] = i – L + 1 。
例子:
Input: arr[] = { 0, 0, 0, 0 }, Q[][] = { { 1, 2 }, { 0, 1 } }
Output: 1 3 2 0
Explanation:
Query1: Updating arr[1] = 1 – 1 + 1, arr[2] = 2 – 1 + 1 modifies arr[] to { 0, 1, 2, 0 }
Query2: Updating arr[0] = 0 – 0 + 1, arr[1] = 1 – 0 + 1 modifies arr[] to { 1, 3, 2, 0 }
Therefore, the required output is 1 3 2 0.
Input: arr[] = { 0, 0, 0, 0 }, Q[][] = { { 1, 3 }, { 0, 1 } }
Output: 1 3 2 3
天真的方法:解决问题的最简单方法是遍历数组Q [] [] ,对于每个查询,遍历给定范围内的所有数组元素,并更新arr [i] + = i – L + 1 。最后,打印数组元素。
时间复杂度: O(N * Q)
辅助空间: O(1)
高效方法:可以使用差分数组的概念来优化上述方法。请按照以下步骤解决问题:
- 初始化两个数组arr1 []和arr2 []并将所有元素初始化为0 。
- 遍历查询数组Q [] [] 。对于(L,R)类型的每个查询,更新arr1 [L] + = 1 , arr1 [R + 1]-= 1和arr2 [R +1]-= R – L + 1 。
- 遍历数组,ARR1 []并存储ARR1的前缀总和[],即ARR1 [I] + = ARR1 [I-1]。
- 遍历数组arr2 []并更新arr2 [i] + = arr2 [i – 1] + arr1 [i] 。
- 最后,打印数组arr2 [] 。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to print the array
void printArray(int arr[], int N)
{
for (int i = 0; i < N; i++) {
cout << arr[i] << " ";
}
}
// Function to perfrom the query in range [L, R]
// such that arr[i] += i - L + 1
void modifyArray(int arr[], int N, int Q[][2],
int cntQuery)
{
// Initialize array
int arr1[N + 1] = { 0 };
int arr2[N + 1] = { 0 };
// Traverse the query array
for (int i = 0; i < cntQuery; i++) {
// Stores range in 1-based index
int L = Q[i][0] + 1, R = Q[i][1] + 1;
// Update arr1[L]
arr1[L]++;
// Update arr1[R + 1]
arr1[R + 1]--;
// Update arr2[R + 1]
arr2[R + 1] -= R - L + 1;
}
// Calculate prefix sum
for (int i = 1; i <= N; i++)
arr1[i] += arr1[i - 1];
// Traverse the array, arr2[]
for (int i = 1; i <= N; i++)
arr2[i] += arr2[i - 1] + arr1[i];
// Copy arr2[] into arr[]
for (int i = 1; i <= N; i++)
arr[i - 1] = arr2[i];
printArray(arr, N);
}
// Driver Code
int main()
{
// Given array
int arr[] = { 0, 0, 0, 0 };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
int Q[][2] = { { 1, 3 }, { 0, 1 } };
// Stores count of query
int cntQuery
= sizeof(Q) / sizeof(Q[0]);
// Function Call
modifyArray(arr, N, Q, cntQuery);
return 0;
}
Java
// Java program to implement
// the above approach
class GFG
{
// Function to print the array
static void printArray(int arr[], int N)
{
for (int i = 0; i < N; i++)
{
System.out.print(arr[i] + " ");
}
}
// Function to perfrom the query in range [L, R]
// such that arr[i] += i - L + 1
static void modifyArray(int arr[], int N, int Q[][],
int cntQuery)
{
// Initialize array
int arr1[] = new int[N + 2];
int arr2[] = new int[N + 2];
// Traverse the query array
for (int i = 0; i < cntQuery; i++)
{
// Stores range in 1-based index
int L = Q[i][0] + 1, R = Q[i][1] + 1;
// Update arr1[L]
arr1[L]++;
// Update arr1[R + 1]
arr1[R + 1]--;
// Update arr2[R + 1]
arr2[R + 1] -= R - L + 1;
}
// Calculate prefix sum
for (int i = 1; i <= N; i++)
arr1[i] += arr1[i - 1];
// Traverse the array, arr2[]
for (int i = 1; i <= N; i++)
arr2[i] += arr2[i - 1] + arr1[i];
// Copy arr2[] into arr[]
for (int i = 1; i <= N; i++)
arr[i - 1] = arr2[i];
printArray(arr, N);
}
// Driver Code
public static void main (String[] args)
{
// Given array
int arr[] = { 0, 0, 0, 0 };
// Size of the array
int N = arr.length;
int Q[][] = { { 1, 3 }, { 0, 1 } };
// Stores count of query
int cntQuery = Q.length;
// Function Call
modifyArray(arr, N, Q, cntQuery);
}
}
// This code is contributed by AnkThon
Python3
# Python3 program to implement
# the above approach
# Function to prthe array
def printArray(arr, N):
print(*arr)
# Function to perfrom the query in range [L, R]
# such that arr[i] += i - L + 1
def modifyArray(arr, N, Q, cntQuery):
# Initialize array
arr1 = [0 for i in range(N + 2)]
arr2 = [0 for i in range(N + 2)]
# Traverse the query array
for i in range(cntQuery):
# Stores range in 1-based index
L = Q[i][0] + 1
R = Q[i][1] + 1
# print(L,R)
# Update arr1[L]
arr1[L] += 1
# Update arr1[R + 1]
arr1[R + 1] -= 1
# Update arr2[R + 1]
arr2[R + 1] -= R - L + 1
# Calculate prefix sum
for i in range(1, N + 1):
arr1[i] += arr1[i - 1]
# Traverse the array, arr2[]
for i in range(1, N + 1):
arr2[i] += arr2[i - 1] + arr1[i]
# Copy arr2[] into arr[]
for i in range(1, N + 1):
arr[i - 1] = arr2[i]
printArray(arr, N)
# Driver Code
if __name__ == '__main__':
# Given array
arr = [0, 0, 0, 0]
# Size of the array
N = len(arr)
Q = [[ 1, 3 ], [ 0, 1 ]]
# Stores count of query
cntQuery = len(Q)
# Function Call
modifyArray(arr, N, Q, cntQuery)
# This code is contributed by mohit kumar 29.
C#
// C# program to implement
// the above approach
using System;
class GFG
{
// Function to print the array
static void printArray(int []arr, int N)
{
for (int i = 0; i < N; i++)
{
Console.Write(arr[i] + " ");
}
}
// Function to perfrom the query in range [L, R]
// such that arr[i] += i - L + 1
static void modifyArray(int []arr, int N, int[,] Q,
int cntQuery)
{
// Initialize array
int []arr1 = new int[N + 2];
int []arr2 = new int[N + 2];
// Traverse the query array
for (int i = 0; i < cntQuery; i++)
{
// Stores range in 1-based index
int L = Q[i,0] + 1, R = Q[i,1] + 1;
// Update arr1[L]
arr1[L]++;
// Update arr1[R + 1]
arr1[R + 1]--;
// Update arr2[R + 1]
arr2[R + 1] -= R - L + 1;
}
// Calculate prefix sum
for (int i = 1; i <= N; i++)
arr1[i] += arr1[i - 1];
// Traverse the array, arr2[]
for (int i = 1; i <= N; i++)
arr2[i] += arr2[i - 1] + arr1[i];
// Copy arr2[] into arr[]
for (int i = 1; i <= N; i++)
arr[i - 1] = arr2[i];
printArray(arr, N);
}
// Driver Code
public static void Main()
{
// Given array
int []arr = { 0, 0, 0, 0 };
// Size of the array
int N = arr.Length;
int [,]Q = { { 1, 3 }, { 0, 1 } };
// Stores count of query
int cntQuery = 2;
// Function Call
modifyArray(arr, N, Q, cntQuery);
}
}
// This code is contributed by bgangwar59.
1 3 2 3
时间复杂度: O(N + Q)
辅助空间: O(N)