🧠
Prefix and Suffix Sum with Hash Map
💡 This approach improves efficiency by precomputing prefix sums and using a hash map to find complement sums quickly, reducing the problem to O(n) time.
Intuition
Compute prefix sums from the left and suffix sums from the right, store suffix sums in a hash map, then for each prefix sum, check if the complement (x - prefix_sum) exists in the suffix sums.
Algorithm
- Compute suffix sums and store them in a hash map with their counts.
- Iterate over prefix sums from the left, for each prefix sum, check if (x - prefix_sum) exists in the suffix sums map.
- If found, update the minimum operations with sum of prefix and suffix counts.
- Return the minimum operations or -1 if no solution.
💡 Using a hash map avoids nested loops by quickly finding complement sums.
def minOperations(nums, x):
n = len(nums)
suffix_sum_map = {0: 0}
suffix_sum = 0
for i in range(n - 1, -1, -1):
suffix_sum += nums[i]
suffix_sum_map[suffix_sum] = n - i
min_ops = suffix_sum_map.get(x, float('inf'))
prefix_sum = 0
for i in range(n):
prefix_sum += nums[i]
if prefix_sum == x:
min_ops = min(min_ops, i + 1)
if (x - prefix_sum) in suffix_sum_map and suffix_sum_map[x - prefix_sum] > i + 1:
min_ops = min(min_ops, i + 1 + suffix_sum_map[x - prefix_sum])
return min_ops if min_ops != float('inf') else -1
# Example usage
if __name__ == '__main__':
print(minOperations([1,1,4,2,3], 5)) # Output: 2
Line Notes
suffix_sum_map = {0: 0}Initialize map with zero sum for empty suffix
for i in range(n - 1, -1, -1):Compute suffix sums from right to left
suffix_sum_map[suffix_sum] = n - iStore suffix sum with count of elements removed
min_ops = suffix_sum_map.get(x, float('inf'))Check if suffix sum alone equals x
prefix_sum += nums[i]Accumulate prefix sum from left
if prefix_sum == x:Check if prefix sum alone equals x
if (x - prefix_sum) in suffix_sum_map and suffix_sum_map[x - prefix_sum] > i + 1:Check for complement suffix sum ensuring no overlap
return min_ops if min_ops != float('inf') else -1Return minimum operations or -1
import java.util.*;
public class Solution {
public static int minOperations(int[] nums, int x) {
int n = nums.length;
Map<Integer, Integer> suffixSumMap = new HashMap<>();
suffixSumMap.put(0, 0);
int suffixSum = 0;
for (int i = n - 1; i >= 0; i--) {
suffixSum += nums[i];
suffixSumMap.put(suffixSum, n - i);
}
int minOps = suffixSumMap.getOrDefault(x, Integer.MAX_VALUE);
int prefixSum = 0;
for (int i = 0; i < n; i++) {
prefixSum += nums[i];
if (prefixSum == x) minOps = Math.min(minOps, i + 1);
int complement = x - prefixSum;
if (suffixSumMap.containsKey(complement) && suffixSumMap.get(complement) > i + 1) {
minOps = Math.min(minOps, i + 1 + suffixSumMap.get(complement));
}
}
return minOps == Integer.MAX_VALUE ? -1 : minOps;
}
public static void main(String[] args) {
System.out.println(minOperations(new int[]{1,1,4,2,3}, 5)); // Output: 2
}
}
Line Notes
Map<Integer, Integer> suffixSumMap = new HashMap<>();Hash map to store suffix sums and counts
suffixSumMap.put(0, 0);Initialize with zero sum for empty suffix
for (int i = n - 1; i >= 0; i--) {Compute suffix sums from right
suffixSumMap.put(suffixSum, n - i);Map suffix sum to count of elements removed
int minOps = suffixSumMap.getOrDefault(x, Integer.MAX_VALUE);Check if suffix sum alone equals x
prefixSum += nums[i];Accumulate prefix sum from left
if (suffixSumMap.containsKey(complement) && suffixSumMap.get(complement) > i + 1) {Check complement suffix sum without overlap
return minOps == Integer.MAX_VALUE ? -1 : minOps;Return result or -1
#include <iostream>
#include <vector>
#include <unordered_map>
#include <climits>
using namespace std;
int minOperations(vector<int>& nums, int x) {
int n = nums.size();
unordered_map<int, int> suffixSumMap;
suffixSumMap[0] = 0;
int suffixSum = 0;
for (int i = n - 1; i >= 0; i--) {
suffixSum += nums[i];
suffixSumMap[suffixSum] = n - i;
}
int minOps = suffixSumMap.count(x) ? suffixSumMap[x] : INT_MAX;
int prefixSum = 0;
for (int i = 0; i < n; i++) {
prefixSum += nums[i];
if (prefixSum == x) minOps = min(minOps, i + 1);
int complement = x - prefixSum;
if (suffixSumMap.count(complement) && suffixSumMap[complement] > i + 1) {
minOps = min(minOps, i + 1 + suffixSumMap[complement]);
}
}
return minOps == INT_MAX ? -1 : minOps;
}
int main() {
vector<int> nums = {1,1,4,2,3};
int x = 5;
cout << minOperations(nums, x) << endl; // Output: 2
return 0;
}
Line Notes
unordered_map<int, int> suffixSumMap;Hash map for suffix sums and counts
suffixSumMap[0] = 0;Initialize with zero sum for empty suffix
for (int i = n - 1; i >= 0; i--) {Compute suffix sums from right
suffixSumMap[suffixSum] = n - i;Map suffix sum to count of elements removed
int minOps = suffixSumMap.count(x) ? suffixSumMap[x] : INT_MAX;Check if suffix sum alone equals x
prefixSum += nums[i];Accumulate prefix sum from left
if (suffixSumMap.count(complement) && suffixSumMap[complement] > i + 1) {Check complement suffix sum without overlap
return minOps == INT_MAX ? -1 : minOps;Return result or -1
function minOperations(nums, x) {
const n = nums.length;
const suffixSumMap = new Map();
suffixSumMap.set(0, 0);
let suffixSum = 0;
for (let i = n - 1; i >= 0; i--) {
suffixSum += nums[i];
suffixSumMap.set(suffixSum, n - i);
}
let minOps = suffixSumMap.has(x) ? suffixSumMap.get(x) : Infinity;
let prefixSum = 0;
for (let i = 0; i < n; i++) {
prefixSum += nums[i];
if (prefixSum === x) minOps = Math.min(minOps, i + 1);
const complement = x - prefixSum;
if (suffixSumMap.has(complement) && suffixSumMap.get(complement) > i + 1) {
minOps = Math.min(minOps, i + 1 + suffixSumMap.get(complement));
}
}
return minOps === Infinity ? -1 : minOps;
}
// Example usage
console.log(minOperations([1,1,4,2,3], 5)); // Output: 2
Line Notes
const suffixSumMap = new Map();Map to store suffix sums and counts
suffixSumMap.set(0, 0);Initialize with zero sum for empty suffix
for (let i = n - 1; i >= 0; i--) {Compute suffix sums from right
suffixSumMap.set(suffixSum, n - i);Map suffix sum to count of elements removed
let minOps = suffixSumMap.has(x) ? suffixSumMap.get(x) : Infinity;Check if suffix sum alone equals x
prefixSum += nums[i];Accumulate prefix sum from left
if (suffixSumMap.has(complement) && suffixSumMap.get(complement) > i + 1) {Check complement suffix sum without overlap
return minOps === Infinity ? -1 : minOps;Return result or -1
Single pass to build suffix sums map and single pass for prefix sums, each O(n). Space for hash map is O(n).
💡 For n=10^5, this approach is efficient enough to run within time limits.
Interview Verdict: Accepted
This approach is efficient and practical for large inputs, suitable for interviews.