Talentd
FleetCode
Make and follow sheets.Sign in

Max Number of K-Sum Pairs solution and explanation

MediumArrayHash TableSortingTwo Pointers6 min read57.5% acceptanceUpdated 9 Apr 2026
Max Number of K-Sum Pairs | Live Coding with Explanation | Leetcode - 1679Algorithms Made Easy · 8:53 · 12K viewsWatch on YouTube
9 more videos on this problem
  1. Max Number of K-Sum Pairs | Live Coding with Explanation | Leetcode - 1679Algorithms Made Easy · 8:53 · 12K views
  2. Leetcode - Max Number of K-Sum Pairs (Python)Timothy H Chang · 5:43 · 9K views
  3. Max Number of K-Sum Pairs | Leetcode 1679 | leetcode solutionEasyLeetcode · 7:52 · 1K views
  4. Max Number of K-Sum Pairs - Leetcode 1679 with step-by-step Explanation | PythonYaps World · 6:03 · 1K views
  5. Max Number of K-Sum Pairs | Leetcode 1679 | Leetcode SolutionEasyLeetcode · 6:35 · 1K views
  6. 1679. Max Number of K-Sum Pairs (Leetcode Medium)Programming Live with Larry · 5:18 · 717 views
  7. LeetCode 1679 | MaxNumber of K-Sum Pairs | JavaScript | Live CodingKun's Dev · 6:46 · 513 views
  8. Leetcode 1679. Max Number of K-Sum Pairs | O(n) SolutionPlacement Corner · 7:51 · 512 views
  9. 💻Solving All LeetCode Problems with PYTHON 🐍 - 1679 Max Number of K-Sum PairsAlex Brou · 6:03 · 318 views
  10. Max Number of K-Sum Pairs | LeetCode 1679 in C++ (Hash Map)LAN Academy · 4:02 · 318 views

The 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.

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.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109
  • 1 <= k <= 109

Approach overview

Problem Overview: Given an integer array and a target value k, you need to form the maximum number of pairs such that each pair sums to k. Every element can be used at most once, so once two numbers form a valid pair they are removed from further consideration.

Approach 1: HashMap Frequency Counting (O(n) time, O(n) space)

This approach scans the array once while storing frequencies in a hash map. For each number x, compute its complement k - x. If the complement already exists in the map with a positive count, you found a valid pair and decrease its frequency. Otherwise, store the current number in the map for future matches. The key insight is that hash lookups are O(1), allowing you to check complements instantly while iterating the array only once. This method works for any unsorted input and is usually the expected optimal solution in interviews. It relies on the efficiency of a hash table combined with a single pass through the array.

Approach 2: Two Pointer Technique on Sorted Array (O(n log n) time, O(1) space)

Another approach sorts the array first, then uses two pointers: one starting at the beginning and the other at the end. At each step, compute the sum of the two values. If the sum equals k, a valid pair is found and both pointers move inward. If the sum is smaller than k, move the left pointer forward to increase the sum. If the sum is larger than k, move the right pointer backward to decrease it. Sorting takes O(n log n) time, but the two-pointer scan itself runs in O(n). This technique is common in problems involving pair sums and demonstrates mastery of the two pointers pattern combined with sorting.

Recommended for interviews: The HashMap approach is typically preferred because it achieves O(n) time without sorting and clearly demonstrates efficient use of a hash-based lookup. The two-pointer solution is also valuable because it shows understanding of sorted array techniques. Explaining both approaches signals strong problem-solving range: hash maps for optimal lookup and pointer techniques for space-efficient scanning.

Approach 1: Using HashMap for Frequency Counting

This approach involves using a hashmap to store the frequency of each number in the array. For each number in the array, check if the complement (k - current number) exists in the hashmap. If it does, form a pair and decrease the frequency of both the current number and its complement in the hashmap. This ensures that no number is reused in forming pairs, optimizing the number of operations possible.

def maxOperations(nums, k):
    count = {}
    operations = 0
    for num in nums:
        complement = k - num
        if count.get(complement, 0) > 0:
            operations += 1
            count[complement] -= 1
        else:
            count[num] = count.get(num, 0) + 1
    return operations

# Example usage
nums = [1, 2, 3, 4]
k = 5
print(maxOperations(nums, k))
import java.util.HashMap;

class Solution {
    public int maxOperations(int[] nums, int k) {
        HashMap<Integer, Integer> map = new HashMap<>();
        int operations = 0;
        for (int num : nums) {
            int complement = k - num;
            if (map.getOrDefault(complement, 0) > 0) {
                operations++;
                map.put(complement, map.get(complement) - 1);
            } else {
                map.put(num, map.getOrDefault(num, 0) + 1);
            }
        }
        return operations;
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        int[] nums = {1, 2, 3, 4};
        int k = 5;
        System.out.println(sol.maxOperations(nums, k));
    }
}
#include <iostream>
#include <unordered_map>
#include <vector>

int maxOperations(std::vector<int>& nums, int k) {
    std::unordered_map<int, int> hashmap;
    int operations = 0;
    for (int num : nums) {
        int complement = k - num;
        if (hashmap[complement] > 0) {
            operations++;
            hashmap[complement]--;
        } else {
            hashmap[num]++;
        }
    }
    return operations;
}

int main() {
    std::vector<int> nums = {1, 2, 3, 4};
    int k = 5;
    std::cout << maxOperations(nums, k) << std::endl;
    return 0;
}
function maxOperations(nums, k) {
    let map = new Map();
    let operations = 0;
    for (let num of nums) {
        let complement = k - num;
        if (map.get(complement) > 0) {
            operations++;
            map.set(complement, map.get(complement) - 1);
        } else {
            map.set(num, (map.get(num) || 0) + 1);
        }
    }
    return operations;
}

// Example Usage
let nums = [1, 2, 3, 4];
let k = 5;
console.log(maxOperations(nums, k));
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 100000

int maxOperations(int* nums, int numsSize, int k) {
    int hash[MAX] = {0}, operations = 0;
    for (int i = 0; i < numsSize; i++) {
        int complement = k - nums[i];
        if (complement >= 0 && hash[complement] > 0) {
            operations++;
            hash[complement]--;
        } else {
            hash[nums[i]]++;
        }
    }
    return operations;
}

int main() {
    int nums[] = {1, 2, 3, 4};
    int size = sizeof(nums) / sizeof(nums[0]);
    int k = 5;
    printf("%d\n", maxOperations(nums, size, k));
    return 0;
}
using System;
using System.Collections.Generic;

public class Solution {
    public int MaxOperations(int[] nums, int k) {
        Dictionary<int, int> map = new Dictionary<int, int>();
        int operations = 0;
        foreach (int num in nums) {
            int complement = k - num;
            if (map.ContainsKey(complement) && map[complement] > 0) {
                operations++;
                map[complement]--;
            } else {
                if (!map.ContainsKey(num)) map[num] = 0;
                map[num]++;
            }
        }
        return operations;
    }

    public static void Main(string[] args) {
        int[] nums = {1, 2, 3, 4};
        int k = 5;
        Solution sol = new Solution();
        Console.WriteLine(sol.MaxOperations(nums, k));
    }
}

The Python solution employs a dictionary to keep track of the number of times each complement is needed. It processes the array while adjusting the counts and tracking the number of operations.

Complexity

Time Complexity: O(n) as it iteratively checks each element, with average constant-time operations for the dictionary.
Space Complexity: O(n), since the dictionary may store counts for up to n numbers.

Try this approach in the editor

Approach 2: Two Pointer Technique on Sorted Array

First sort the array, which allows the use of a two-pointer technique to find pairs. One pointer starts at the beginning and the other at the end of the sorted array. If the sum of the elements at these pointers equals k, increase the operations count and move both pointers. If the sum is less than k, move the left pointer to increase the sum, otherwise, move the right pointer to decrease the sum, thus efficiently finding all possible pairs.

def maxOperations(nums, k):
    nums.sort()
    left, right = 0, len(nums) - 1
    operations = 0
    while left < right:
        current_sum = nums[left] + nums[right]
        if current_sum == k:
            operations += 1
            left += 1
            right -= 1
        elif current_sum < k:
            left += 1
        else:
            right -= 1
    return operations

# Example usage
nums = [1, 2, 3, 4]
k = 5
print(maxOperations(nums, k))
import java.util.Arrays;

class Solution {
    public int maxOperations(int[] nums, int k) {
        Arrays.sort(nums);
        int operations = 0, left = 0, right = nums.length - 1;
        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == k) {
                operations++;
                left++;
                right--;
            } else if (sum < k) {
                left++;
            } else {
                right--;
            }
        }
        return operations;
    }

    public static void main(String[] args) {
        Solution sol = new Solution();
        int[] nums = {1, 2, 3, 4};
        int k = 5;
        System.out.println(sol.maxOperations(nums, k));
    }
}
#include <iostream>
#include <vector>
#include <algorithm>

int maxOperations(std::vector<int>& nums, int k) {
    std::sort(nums.begin(), nums.end());
    int operations = 0, left = 0, right = nums.size() - 1;
    while (left < right) {
        int sum = nums[left] + nums[right];
        if (sum == k) {
            operations++;
            left++;
            right--;
        } else if (sum < k) {
            left++;
        } else {
            right--;
        }
    }
    return operations;
}

int main() {
    std::vector<int> nums = {1, 2, 3, 4};
    int k = 5;
    std::cout << maxOperations(nums, k) << std::endl;
    return 0;
}
function maxOperations(nums, k) {
    nums.sort((a, b) => a - b);
    let left = 0, right = nums.length - 1;
    let operations = 0;
    while (left < right) {
        let sum = nums[left] + nums[right];
        if (sum === k) {
            operations++;
            left++;
            right--;
        } else if (sum < k) {
            left++;
        } else {
            right--;
        }
    }
    return operations;
}

// Example Usage
let nums = [1, 2, 3, 4];
k = 5;
console.log(maxOperations(nums, k));
#include <stdio.h>
#include <stdlib.h>

int compare(const void *a, const void *b) {
    return *(int *)a - *(int *)b;
}

int maxOperations(int* nums, int numsSize, int k) {
    qsort(nums, numsSize, sizeof(int), compare);
    int left = 0, right = numsSize - 1, operations = 0;
    while (left < right) {
        int sum = nums[left] + nums[right];
        if (sum == k) {
            operations++;
            left++;
            right--;
        } else if (sum < k) {
            left++;
        } else {
            right--;
        }
    }
    return operations;
}

int main() {
    int nums[] = {1, 2, 3, 4};
    int size = sizeof(nums) / sizeof(nums[0]);
    int k = 5;
    printf("%d\n", maxOperations(nums, size, k));
    return 0;
}
using System;

public class Solution {
    public int MaxOperations(int[] nums, int k) {
        Array.Sort(nums);
        int operations = 0, left = 0, right = nums.Length - 1;
        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == k) {
                operations++;
                left++;
                right--;
            } else if (sum < k) {
                left++;
            } else {
                right--;
            }
        }
        return operations;
    }

    public static void Main(string[] args) {
        int[] nums = {1, 2, 3, 4};
        int k = 5;
        Solution sol = new Solution();
        Console.WriteLine(sol.MaxOperations(nums, k));
    }
}

Python's sorted inbuilt function is leveraged in this approach, maintaining scope for fast retrieval of pairs, followed by a classic two-pointer method for possible pair comprehension with reduced overhead.

Complexity

Time Complexity: O(n log n) because sorting dominates the time complexity, while the two-pointer action runs in O(n).
Space Complexity: O(1), manipulating in-place only with auxiliary pointers involved.

Try this approach in the editor

Approach 3: Sorting

We sort nums. Then l and r point to the first and last elements of nums respectively, and we compare the sum s of the two integers with k.

  • If s = k, it means that we have found two integers whose sum is k. We increment the answer and then move l and r towards the middle;
  • If s > k, then we move the r pointer to the left;
  • If s < k, then we move the l pointer to the right;
  • We continue the loop until l geq r.

After the loop ends, we return the answer.

The time complexity is O(n times log n), and the space complexity is O(log n). Here, n is the length of nums.

function maxOperations(nums: number[], k: number): number {
    const cnt = new Map();
    let ans = 0;
    for (const x of nums) {
        if (cnt.get(k - x)) {
            cnt.set(k - x, cnt.get(k - x) - 1);
            ++ans;
        } else {
            cnt.set(x, (cnt.get(x) | 0) + 1);
        }
    }
    return ans;
}
func maxOperations(nums []int, k int) int {
	sort.Ints(nums)
	l, r, ans := 0, len(nums)-1, 0
	for l < r {
		s := nums[l] + nums[r]
		if s == k {
			ans++
			l++
			r--
		} else if s > k {
			r--
		} else {
			l++
		}
	}
	return ans
}
impl Solution {
    pub fn max_operations(nums: Vec<i32>, k: i32) -> i32 {
        let mut nums = nums.clone();
        nums.sort();
        let (mut l, mut r, mut ans) = (0, nums.len() - 1, 0);
        while l < r {
            match nums[l] + nums[r] {
                sum if sum == k => {
                    ans += 1;
                    l += 1;
                    r -= 1;
                }
                sum if sum > k => {
                    r -= 1;
                }
                _ => {
                    l += 1;
                }
            }
        }
        ans
    }
}
Try this approach in the editor

Approach 4: Hash Table

We use a hash table cnt to record the current remaining integers and their occurrence counts.

We iterate over nums. For the current integer x, we check if k - x is in cnt. If it exists, it means that we have found two integers whose sum is k. We increment the answer and then decrement the occurrence count of k - x; otherwise, we increment the occurrence count of x.

After the iteration ends, we return the answer.

The time complexity is O(n), and the space complexity is O(n). Here, n is the length of nums.

func maxOperations(nums []int, k int) (ans int) {
	cnt := map[int]int{}
	for _, x := range nums {
		if cnt[k-x] > 0 {
			cnt[k-x]--
			ans++
		} else {
			cnt[x]++
		}
	}
	return
}
impl Solution {
    pub fn max_operations(nums: Vec<i32>, k: i32) -> i32 {
        let mut cnt = std::collections::HashMap::new();
        let mut ans = 0;
        for x in nums {
            let m = k - x;
            if let Some(v) = cnt.get_mut(&m) {
                ans += 1;
                *v -= 1;
                if *v == 0 {
                    cnt.remove(&m);
                }
            } else if let Some(v) = cnt.get_mut(&x) {
                *v += 1;
            } else {
                cnt.insert(x, 1);
            }
        }
        ans
    }
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Using HashMap for Frequency Counting

Time Complexity: O(n) as it iteratively checks each element, with average constant-time operations for the dictionary.
Space Complexity: O(n), since the dictionary may store counts for up to n numbers.

Two Pointer Technique on Sorted Array

Time Complexity: O(n log n) because sorting dominates the time complexity, while the two-pointer action runs in O(n).
Space Complexity: O(1), manipulating in-place only with auxiliary pointers involved.

Sorting–
Hash Table–

Complexity analysis

ApproachTimeSpaceWhen to Use
HashMap Frequency CountingO(n)O(n)Best general solution for unsorted arrays and interview settings
Two Pointer on Sorted ArrayO(n log n)O(1)Useful when array can be sorted or when minimizing extra memory

Frequently asked questions

Is Max Number of K-Sum Pairs easy or hard?

The problem is generally categorized as Medium difficulty. The core idea is straightforward once you recognize the complement pattern, but identifying the optimal O(n) HashMap strategy or the sorted two-pointer alternative requires familiarity with common array interview patterns.

Max Number of K-Sum Pairs Python/Java solution

Python and Java solutions typically implement the HashMap frequency method. Python uses a dictionary for constant-time lookups, while Java commonly uses HashMap<Integer, Integer>. Both implementations achieve O(n) time and O(n) space complexity.

How to solve Max Number of K-Sum Pairs in O(n)?

Use a HashMap to store counts of numbers seen so far. While iterating through the array, compute the complement k - x for each element. If the complement exists with a positive count, form a pair and decrease its frequency; otherwise store the current number. This guarantees a single pass with O(n) time.

What is the best approach for Max Number of K-Sum Pairs?

The most efficient approach uses a HashMap to track frequencies of numbers while scanning the array. For each value x, check if the complement k - x already exists in the map. This method runs in O(n) time with O(n) space and avoids the need to sort the array.

Is Max Number of K-Sum Pairs asked at Google/Amazon/Meta?

Pair-sum problems and hash-map complement patterns are frequently asked in interviews at companies like Amazon, Meta, and Google. Variations such as Two Sum, K-Sum, and pair counting problems are common because they test array processing and hash table usage.

What data structure is used in Max Number of K-Sum Pairs?

The optimal approach relies on a HashMap (or dictionary) to store frequencies of elements. Another common technique uses the two-pointer pattern after sorting the array, which avoids extra memory but increases time complexity due to sorting.

What is the time complexity of Max Number of K-Sum Pairs?

The optimal solution runs in O(n) time using a HashMap for constant-time complement lookups. A sorting-based solution using two pointers runs in O(n log n) time due to the sorting step, followed by an O(n) scan.

Comments

Now write it yourselfClose this page and solve Max Number of K-Sum Pairs in the editor, without looking.
Practise Max Number of K-Sum Pairs