给定一个由N个不同整数组成的数组arr []和一个由Q个查询组成的数组query [] ,每个查询的任务是在数组中查找query [i]并从头开始计算数组元素之和的最小值数组的末尾直到query [i]为止。
例子:
Input: arr[] = {2, 3, 6, 7, 4, 5, 30}, Q = 2, queries[] = {6, 5}
Output: 11 27
Explanation:
Query 1: Sum from start = 2 + 3 + 6 = 11. Sum from end = 30 + 5 + 4 + 7 + 6 = 52. Therefore, 11 is the required answer.
Query 2: Sum from start = 27. Sum from end = 35. Therefore, 27 is the required answer.
Input: arr[] = {1, 2, -3, 4}, Q = 2, queries[] = {4, 2}
Output: 4 2
天真的方法:最简单的方法是遍历每个查询的上查询数组[i] ,并从数组的开头和结尾开始计算总和。最后,打印获得的总和的最小值。
下面是上述方法的实现:
C++
// C++ implementation
// of the above approach
#include
using namespace std;
// Function to calclate the minimum
// sum from either end of the arrays
// for the given queries
void calculateQuery(int arr[], int N,
int query[], int M)
{
// Traverse the query[] array
for (int i = 0; i < M; i++) {
int X = query[i];
// Stores sum from start
// and end of the array
int sum_start = 0, sum_end = 0;
// Calculate distance from start
for (int j = 0; j < N; j++) {
sum_start += arr[j];
if (arr[j] == X)
break;
}
// Calculate distance from end
for (int j = N - 1; j >= 0; j--) {
sum_end += arr[j];
if (arr[j] == X)
break;
}
cout << min(sum_end, sum_start) << " ";
}
}
// Driver Code
int main()
{
int arr[] = { 2, 3, 6, 7, 4, 5, 30 };
int queries[] = { 6, 5 };
int N = sizeof(arr) / sizeof(arr[0]);
int M = sizeof(queries)
/ sizeof(queries[0]);
calculateQuery(arr, N, queries, M);
return 0;
}
Java
// Java implementation of the
// above approach
import java.util.*;
import java.lang.*;
public class GFG
{
// Function to calclate the minimum
// sum from either end of the arrays
// for the given queries
static void calculateQuery(int arr[], int N,
int query[], int M)
{
// Traverse the query[] array
for (int i = 0; i < M; i++)
{
int X = query[i];
// Stores sum from start
// and end of the array
int sum_start = 0, sum_end = 0;
// Calculate distance from start
for (int j = 0; j < N; j++)
{
sum_start += arr[j];
if (arr[j] == X)
break;
}
// Calculate distance from end
for (int j = N - 1; j >= 0; j--)
{
sum_end += arr[j];
if (arr[j] == X)
break;
}
System.out.print(Math.min(sum_end, sum_start) + " ");
}
}
// Driver Code
public static void main (String[] args)
{
int arr[] = { 2, 3, 6, 7, 4, 5, 30 };
int queries[] = { 6, 5 };
int N = arr.length;
int M = queries.length;
calculateQuery(arr, N, queries, M);
}
}
// This code is contributed by jana_sayantan.
Python3
# Python 3 implementation
# of the above approach
# Function to calclate the minimum
# sum from either end of the arrays
# for the given queries
def calculateQuery(arr, N, query, M):
# Traverse the query[] array
for i in range(M):
X = query[i]
# Stores sum from start
# and end of the array
sum_start = 0
sum_end = 0
# Calculate distance from start
for j in range(N):
sum_start += arr[j]
if (arr[j] == X):
break
# Calculate distance from end
for j in range(N - 1, -1, -1):
sum_end += arr[j]
if (arr[j] == X):
break
print(min(sum_end, sum_start), end=" ")
# Driver Code
if __name__ == "__main__":
arr = [2, 3, 6, 7, 4, 5, 30]
queries = [6, 5]
N = len(arr)
M = len(queries)
calculateQuery(arr, N, queries, M)
# This code is contributed by chitranayal.
C#
// C# implementation
// of the above approach
using System;
class GFG {
// Function to calclate the minimum
// sum from either end of the arrays
// for the given queries
static void calculateQuery(int[] arr, int N,
int[] query, int M)
{
// Traverse the query[] array
for (int i = 0; i < M; i++) {
int X = query[i];
// Stores sum from start
// and end of the array
int sum_start = 0, sum_end = 0;
// Calculate distance from start
for (int j = 0; j < N; j++) {
sum_start += arr[j];
if (arr[j] == X)
break;
}
// Calculate distance from end
for (int j = N - 1; j >= 0; j--) {
sum_end += arr[j];
if (arr[j] == X)
break;
}
Console.Write(Math.Min(sum_end, sum_start) + " ");
}
}
// Driver code
static void Main()
{
int[] arr = { 2, 3, 6, 7, 4, 5, 30 };
int[] queries = { 6, 5 };
int N = arr.Length;
int M = queries.Length;
calculateQuery(arr, N, queries, M);
}
}
// This code is contributed by divyesh072019.
C++
// C++ implementation
// of the above approach
#include
using namespace std;
// Function to find the minimum sum
// for the given queries
void calculateQuery(int arr[], int N,
int query[], int M)
{
// Stores prefix and suffix sums
int prefix = 0, suffix = 0;
// Stores pairs of prefix and suffix sums
unordered_map > mp;
// Traverse the array
for (int i = 0; i < N; i++) {
// Add element to prefix
prefix += arr[i];
// Store prefix for each element
mp[arr[i]].first = prefix;
}
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--) {
// Add element to suffix
suffix += arr[i];
// Storing suffix for each element
mp[arr[i]].second = suffix;
}
// Travere the array queries[]
for (int i = 0; i < M; i++) {
int X = query[i];
// Minimum of suffix
// and prefix sums
cout << min(mp[X].first,
mp[X].second)
<< " ";
}
}
// Driver Code
int main()
{
int arr[] = { 2, 3, 6, 7, 4, 5, 30 };
int queries[] = { 6, 5 };
int N = sizeof(arr) / sizeof(arr[0]);
int M = sizeof(queries) / sizeof(queries[0]);
calculateQuery(arr, N, queries, M);
return 0;
}
Java
// Java implementation
// of the above approach
import java.util.*;
class GFG
{
static class pair
{
E first;
P second;
public pair(E first, P second)
{
this.first = first;
this.second = second;
}
}
// Function to find the minimum sum
// for the given queries
@SuppressWarnings({ "unchecked", "rawtypes" })
static void calculateQuery(int arr[], int N,
int query[], int M)
{
// Stores prefix and suffix sums
int prefix = 0, suffix = 0;
// Stores pairs of prefix and suffix sums
HashMap mp = new HashMap<>();
// Traverse the array
for (int i = 0; i < N; i++) {
// Add element to prefix
prefix += arr[i];
// Store prefix for each element
mp.put(arr[i], new pair(prefix,0));
}
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--) {
// Add element to suffix
suffix += arr[i];
// Storing suffix for each element
mp.put(arr[i], new pair(mp.get(arr[i]).first,suffix));
}
// Travere the array queries[]
for (int i = 0; i < M; i++) {
int X = query[i];
// Minimum of suffix
// and prefix sums
System.out.print(Math.min((int)mp.get(X).first,
(int)mp.get(X).second)
+ " ");
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 2, 3, 6, 7, 4, 5, 30 };
int queries[] = { 6, 5 };
int N = arr.length;
int M = queries.length;
calculateQuery(arr, N, queries, M);
}
}
// This code is contributed by 29AjayKumar
C#
// C# implementation
// of the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find the minimum sum
// for the given queries
static void calculateQuery(int[] arr, int N,
int[] query, int M)
{
// Stores prefix and suffix sums
int prefix = 0, suffix = 0;
// Stores pairs of prefix and suffix sums
Dictionary> mp =
new Dictionary>();
// Traverse the array
for (int i = 0; i < N; i++)
{
// Add element to prefix
prefix += arr[i];
// Store prefix for each element
mp[arr[i]] = new Tuple(prefix, 0);
}
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--)
{
// Add element to suffix
suffix += arr[i];
// Storing suffix for each element
mp[arr[i]] = new Tuple(mp[arr[i]].Item1, suffix);
}
// Travere the array queries[]
for (int i = 0; i < M; i++)
{
int X = query[i];
// Minimum of suffix
// and prefix sums
Console.Write(Math.Min(mp[X].Item1, mp[X].Item2) + " ");
}
}
// Driver code
static void Main() {
int[] arr = { 2, 3, 6, 7, 4, 5, 30 };
int[] queries = { 6, 5 };
int N = arr.Length;
int M = queries.Length;
calculateQuery(arr, N, queries, M);
}
}
// This code is contributed by divyeshrabadiya07.
11 27
时间复杂度: O(Q * N)
辅助空间: O(1)
高效的方法:可以通过使用额外的空间以及前缀和和后缀和的概念来优化上述方法,并以恒定的计算复杂性来回答每个查询。这个想法是预处理每个索引的前缀和后缀总和。请按照以下步骤解决问题:
- 初始化两个变量,比如prefix和suffix 。
- 初始化一个无序映射(例如mp),以将数组元素映射为对的键,其中第一个值给出前缀和,第二个值给出后缀和。
- 遍历数组,并继续添加arr [i]作为前缀,并将其存储在映射中,并以arr [i]作为键,并将前缀作为值。
- 反向遍历数组,并继续将arr [i]添加到后缀,并以arr [i]作为键并将后缀作为值存储在映射中。
- 现在遍历数组query [],并为每个查询query [i]打印mp [queries [i]]。first和mp [queries [i]]。second的最小值。
下面是上述方法的实现:
C++
// C++ implementation
// of the above approach
#include
using namespace std;
// Function to find the minimum sum
// for the given queries
void calculateQuery(int arr[], int N,
int query[], int M)
{
// Stores prefix and suffix sums
int prefix = 0, suffix = 0;
// Stores pairs of prefix and suffix sums
unordered_map > mp;
// Traverse the array
for (int i = 0; i < N; i++) {
// Add element to prefix
prefix += arr[i];
// Store prefix for each element
mp[arr[i]].first = prefix;
}
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--) {
// Add element to suffix
suffix += arr[i];
// Storing suffix for each element
mp[arr[i]].second = suffix;
}
// Travere the array queries[]
for (int i = 0; i < M; i++) {
int X = query[i];
// Minimum of suffix
// and prefix sums
cout << min(mp[X].first,
mp[X].second)
<< " ";
}
}
// Driver Code
int main()
{
int arr[] = { 2, 3, 6, 7, 4, 5, 30 };
int queries[] = { 6, 5 };
int N = sizeof(arr) / sizeof(arr[0]);
int M = sizeof(queries) / sizeof(queries[0]);
calculateQuery(arr, N, queries, M);
return 0;
}
Java
// Java implementation
// of the above approach
import java.util.*;
class GFG
{
static class pair
{
E first;
P second;
public pair(E first, P second)
{
this.first = first;
this.second = second;
}
}
// Function to find the minimum sum
// for the given queries
@SuppressWarnings({ "unchecked", "rawtypes" })
static void calculateQuery(int arr[], int N,
int query[], int M)
{
// Stores prefix and suffix sums
int prefix = 0, suffix = 0;
// Stores pairs of prefix and suffix sums
HashMap mp = new HashMap<>();
// Traverse the array
for (int i = 0; i < N; i++) {
// Add element to prefix
prefix += arr[i];
// Store prefix for each element
mp.put(arr[i], new pair(prefix,0));
}
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--) {
// Add element to suffix
suffix += arr[i];
// Storing suffix for each element
mp.put(arr[i], new pair(mp.get(arr[i]).first,suffix));
}
// Travere the array queries[]
for (int i = 0; i < M; i++) {
int X = query[i];
// Minimum of suffix
// and prefix sums
System.out.print(Math.min((int)mp.get(X).first,
(int)mp.get(X).second)
+ " ");
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 2, 3, 6, 7, 4, 5, 30 };
int queries[] = { 6, 5 };
int N = arr.length;
int M = queries.length;
calculateQuery(arr, N, queries, M);
}
}
// This code is contributed by 29AjayKumar
C#
// C# implementation
// of the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find the minimum sum
// for the given queries
static void calculateQuery(int[] arr, int N,
int[] query, int M)
{
// Stores prefix and suffix sums
int prefix = 0, suffix = 0;
// Stores pairs of prefix and suffix sums
Dictionary> mp =
new Dictionary>();
// Traverse the array
for (int i = 0; i < N; i++)
{
// Add element to prefix
prefix += arr[i];
// Store prefix for each element
mp[arr[i]] = new Tuple(prefix, 0);
}
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--)
{
// Add element to suffix
suffix += arr[i];
// Storing suffix for each element
mp[arr[i]] = new Tuple(mp[arr[i]].Item1, suffix);
}
// Travere the array queries[]
for (int i = 0; i < M; i++)
{
int X = query[i];
// Minimum of suffix
// and prefix sums
Console.Write(Math.Min(mp[X].Item1, mp[X].Item2) + " ");
}
}
// Driver code
static void Main() {
int[] arr = { 2, 3, 6, 7, 4, 5, 30 };
int[] queries = { 6, 5 };
int N = arr.Length;
int M = queries.Length;
calculateQuery(arr, N, queries, M);
}
}
// This code is contributed by divyeshrabadiya07.
11 27
时间复杂度: O(M + N)
辅助空间: O(N)