Problem
You are given an integer array nums
and an integer k
.
In one operation, you can pick two numbers from the array whose sum equals k
and remove them from the array.
Return the maximum number of operations you can perform on the array.
Examples
Example 1:
Input: nums = [1,2,3,4], k = 5
Output: 2
Explanation: Starting with nums = [1,2,3,4]:
- Remove numbers 1 and 4, then nums = [2,3]
- Remove numbers 2 and 3, then nums = []
There are no more pairs that sum up to 5, hence a total of 2 operations.
Example 2:
Input: nums = [3,1,3,4,3], k = 6
Output: 1
Explanation: Starting with nums = [3,1,3,4,3]:
- Remove the first two 3's, then nums = [1,4,3]
There are no more pairs that sum up to 6, hence a total of 1 operation.
Solution
This is problem is close to 2Sum Problem.
Method 1 - Using Hashmap but two pass
Here is the approach:
- Use a frequency map (or dictionary) to count the occurrences of each element in the array.
- Iterate through the array, and for each element, check if its complement (
k - num
) exists in the frequency map with a sufficient count. - If both the element and its complement have valid counts, decrement the counts of both elements in the frequency map and increment the operation count.
- Continue this until all possible pairs are exhausted.
Code
Java
public class Solution {
public int maxOperations(int[] nums, int k) {
// Create a frequency map of elements in the array
Map<Integer, Long> freqMap = Arrays.stream(nums).boxed().collect(
Collectors.groupingBy(
Function.identity(),
HashMap::new,
Collectors.counting()
)
);
int ans = 0;
for (int num : nums) {
// Check if the current number and its complement have valid counts
if (freqMap.get(num) >= 1 && freqMap.containsKey(k - num) && freqMap.get(k - num) >= 1) {
freqMap.put(num, freqMap.get(num) - 1);
if (freqMap.get(k - num) < 1) {
continue;
}
freqMap.put(k - num, freqMap.get(k - num) - 1);
ans++;
}
}
return ans;
}
}
Python
class Solution:
def max_operations(self, nums: List[int], k: int) -> int:
# Create a frequency map of elements in the array
freq_map = defaultdict(int)
for num in nums:
freq_map[num] += 1
ans = 0
for num in nums:
# Check if the current number and its complement have valid counts
if freq_map[num] >= 1 and freq_map[k - num] >= 1:
freq_map[num] -= 1
if freq_map[k - num] < 1:
continue
freq_map[k - num] -= 1
ans += 1
return ans
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(n)
Method 2 - Using Hashmap and One Pass
Here is the approach:
- Use a HashMap (or dictionary) to keep track of the occurrences of each element.
- As you iterate through the array, calculate the complement (
k - nums[i]
). - Check if the complement exists in the HashMap.
- If it exists, increment the count and decrement the occurrence of the complement in the HashMap. Remove the complement from the HashMap if its count reaches zero.
- If the complement does not exist, update the HashMap with the current element.
Code
Java
public class Solution {
public int maxOperations(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>(); // HashMap to store counts of elements
int count = 0; // Counter for number of operations
for (int i = 0; i < nums.length; i++) {
int rem = k - nums[i]; // Calculate the complement
if (map.containsKey(rem)) {
count++; // Increment count if complement is found
map.put(rem, map.get(rem) - 1); // Decrement the occurrence count of the complement
if (map.get(rem) == 0) {
map.remove(rem); // Remove the complement from HashMap if its count reaches zero
}
} else {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); // Update HashMap with the current element
}
}
return count;
}
}
Python
class Solution:
def max_operations(self, nums: List[int], k: int) -> int:
count = 0 # Counter for number of operations
num_map = defaultdict(int) # Dictionary to store counts of elements
for num in nums:
rem = k - num # Calculate the complement
if num_map[rem] > 0:
count += 1 # Increment count if complement is found
num_map[rem] -= 1 # Decrement the occurrence count of the complement
if num_map[rem] == 0:
del num_map[rem] # Remove the complement from dictionary if its count reaches zero
else:
num_map[num] += 1 # Update dictionary with the current element
return count
Complexity
- ⏰ Time complexity:
O(n)
- 🧺 Space complexity:
O(n)