📌  相关文章
📜  查询以从数组的任一端查找数组元素的最小总和

📅  最后修改于: 2021-09-06 06:25:09             🧑  作者: Mango

给定一个由N 个不同整数组成的数组arr[]和一个由Q 个查询组成的数组查询 [] ,每个查询的任务是在数组中找到查询 [i]并从开始计算数组元素总和的最小值和数组的结尾到查询 [i]

例子:

朴素的方法:最简单的方法是为每个查询遍历数组 upro queries[i]并从数组的末尾和开头计算总和。最后,打印获得的和的最小值。

下面是上述方法的实现:

C++
// C++ implementation
// of the above approach
 
#include 
using namespace std;
 
// Function to calculate 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.


Javascript


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.


Javascript


输出:
11 27

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

高效的方法:上述方法可以通过使用额外的空间和前缀和和后缀和的概念进行优化,并以恒定的计算复杂度回答每个查询。这个想法是预处理每个索引的前缀和后缀和。请按照以下步骤解决问题:

  • 初始化两个变量,比如prefixsuffix
  • 初始化一个无序映射,比如mp,将数组元素作为映射到对,其中第一个值给出前缀和,第二个值给出后缀和。
  • 遍历数组并不断添加arr[i]到前缀并将其存储在地图中,以arr[i]作为键和前缀作为值。
  • 反向遍历数组,不断添加arr[i]到后缀并以arr[i]为键,后缀为值存储在映射中。
  • 现在遍历数组queries[]并且对于每个查询queries[i] ,打印mp[queries[i]].firstmp[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.

Javascript


输出:
11 27

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

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