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

📅  最后修改于: 2021-04-17 16:17:39             🧑  作者: Mango

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

例子:

天真的方法:最简单的方法是遍历每个查询的上查询数组[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)

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

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

输出:
11 27

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