删除部分后缀后 K 数组的最小公共总和
给定二维列表arr[][]中不同大小的K (K > 2) 个数组,其中每个数组中的元素都是非负数。从每个数组中删除部分后缀(可能没有)后,找到 K 个数组的最小公共和。
例子:
Input: K = 3,
arr = {{5, 2, 4},
{1, 4, 1, 1},
{2, 3}}
Output: 5
Explanation: 1st array: [5, 5+2, 5+2+4], = {5, 7, 11} remove suffix array [2, 4]
2nd array: [1, 1+4, 1+4+1, 1+4+1+1], = {1, 5, 6, 7} remove suffix array [1, 1]
3rd array: [2, 2+3 ], = {2, 5} don’t remove any thing
5 is the minimum common sum of given arrays after removing part of the suffix.
Input: K = 4
arr = {{5, 3},
{1, 4},
{3, 1},
{9, 3, 1}}
Output: -1
Explanation: There is so common sum at all, therefore print -1.
方法:问题的解决方案是基于前缀 sum和hashing 。对所有数组使用前缀总和,并对映射或哈希表中的前缀总和值进行散列。现在对于第一个前缀和数组,使用哈希表找到所有前缀和数组中存在的最小值。请按照以下步骤解决问题:
- 获取所有数组的前缀和。在进行前缀和散列时,哈希图中的前缀和的值以检查该前缀和是否存在于所有数组中。
- 因为预计算是在非负整数上完成的。预计算后,数组将按非递减顺序排列。
- 现在遍历第一个前缀和数组并 -
- 检查当前前缀和是否存在于所有数组中或不使用哈希映射。
- 如果存在,则停止迭代并将其作为最小公共总和返回。
- 如果没有,则继续迭代。
- 完整迭代完成后,如果没有找到这样的前缀和,则在给定条件下不能形成公共和。
下面是上述方法的实现。
C++
// C++ program to implement the approach
#include
using namespace std;
// Precompute for every array
void pre_compute(vector >& arr,
int K,
unordered_map& mp)
{
for (int i = 0; i < K; i++) {
// Size of ith row stored in n
int n = arr[i].size();
mp[arr[i][0]]
= min(mp[arr[i][0]] + 1, i + 1);
// Precomputing ith row
for (int j = 1; j < n; j++) {
arr[i][j] += arr[i][j - 1];
mp[arr[i][j]]
= min(mp[arr[i][j]] + 1,
i + 1);
}
}
}
// Function to calculate minimum common sum
int min_common_sum(vector >& arr,
int K)
{
unordered_map mp;
// Function call to precompute
// every row in arr
pre_compute(arr, K, mp);
for (int i = 0; i < arr[0].size(); i++) {
if (mp[arr[0][i]] == K)
return arr[0][i];
}
return -1;
}
// Driver code
int main()
{
int K = 3;
// All k arrays are stored using 2D vector
vector > arr
= { { 5, 2, 4 }, { 1, 4, 1, 1 }, { 2, 3 } };
int ans = min_common_sum(arr, K);
cout << ans;
return 0;
}
Java
// Java program to implement the approach
import java.util.*;
class GFG
{
// Precompute for every array
static HashMap pre_compute(int[][] arr,
int K,
HashMap mp)
{
for (int i = 0; i < K; i++) {
// Size of ith row stored in n
int n = arr[i].length;
if(mp.containsKey(arr[i][0]))
mp.put(arr[i][0], Math.min(mp.get(arr[i][0]) + 1, i + 1));
else
mp.put(arr[i][0], Math.min(1, i + 1));
// Precomputing ith row
for (int j = 1; j < n; j++) {
arr[i][j] += arr[i][j - 1];
if(mp.containsKey(arr[i][j]))
mp.put(arr[i][j], Math.min(mp.get(arr[i][j]) + 1, i + 1));
else
mp.put(arr[i][j], Math.min(1, i + 1));
}
}
return mp;
}
// Function to calculate minimum common sum
static int min_common_sum(int[][] arr,
int K)
{
HashMap mp = new HashMap();
// Function call to precompute
// every row in arr
mp = pre_compute(arr, K, mp);
for (int i = 0; i < arr[0].length; i++) {
if (mp.get(arr[0][i]) == K)
return arr[0][i];
}
return -1;
}
// Driver code
public static void main(String[] args)
{
int K = 3;
// All k arrays are stored using 2D vector
int[][] arr
= { { 5, 2, 4 ,0}, { 1, 4, 1, 1 }, { 2, 3,0,0 } };
int ans = min_common_sum(arr, K);
System.out.print(ans);
}
}
// This code is contributed by shikhasingrajput
Python3
# python3 program to implement the approach
# Precompute for every array
def pre_compute(arr, K, mp):
for i in range(0, K):
# Size of ith row stored in n
n = len(arr[i])
mp[arr[i][0]] = min(
(mp[arr[i][0]] if arr[i][0] in mp else 0) + 1, i + 1)
# Precomputing ith row
for j in range(1, n):
arr[i][j] += arr[i][j - 1]
mp[arr[i][j]] = min((mp[arr[i][j]] if arr[i][j] in mp else 0) + 1,
i + 1)
# Function to calculate minimum common sum
def min_common_sum(arr, K):
mp = {}
# Function call to precompute
# every row in arr
pre_compute(arr, K, mp)
for i in range(0, len(arr[0])):
if (mp[arr[0][i]] == K):
return arr[0][i]
return -1
# Driver code
if __name__ == "__main__":
K = 3
# All k arrays are stored using 2D vector
arr = [[5, 2, 4], [1, 4, 1, 1], [2, 3]]
ans = min_common_sum(arr, K)
print(ans)
# This code is contributed by rakeshsahni
C#
// C# program to implement the approach
using System;
using System.Collections.Generic;
public class GFG
{
// Precompute for every array
static Dictionary pre_compute(int[,] arr,
int K,
Dictionary mp)
{
for (int i = 0; i < K; i++) {
// Size of ith row stored in n
int n = arr.GetLength(1);
if(mp.ContainsKey(arr[i,0]))
mp[arr[i,0]]= Math.Min(mp[arr[i,0]] + 1, i + 1);
else
mp.Add(arr[i,0], Math.Min(1, i + 1));
// Precomputing ith row
for (int j = 1; j < n; j++) {
arr[i,j] += arr[i,j - 1];
if(mp.ContainsKey(arr[i,j]))
mp[arr[i,j]] = Math.Min(mp[arr[i,j]] + 1, i + 1);
else
mp.Add(arr[i,j], Math.Min(1, i + 1));
}
}
return mp;
}
// Function to calculate minimum common sum
static int min_common_sum(int[,] arr,
int K)
{
Dictionary mp = new Dictionary();
// Function call to precompute
// every row in arr
mp = pre_compute(arr, K, mp);
for (int i = 0; i < arr.GetLength(0); i++) {
if (mp[arr[0,i]] == K)
return arr[0,i];
}
return -1;
}
// Driver code
public static void Main(String[] args)
{
int K = 3;
// All k arrays are stored using 2D vector
int[,] arr
= { { 5, 2, 4 ,0}, { 1, 4, 1, 1 }, { 2, 3,0,0 } };
int ans = min_common_sum(arr, K);
Console.Write(ans);
}
}
// This code is contributed by 29AjayKumar
Javascript
5
时间复杂度: O(K * N) 其中 N 是数组的最大大小
辅助空间: O(K * N)