Choose K Elements With Maximum Sum solution and explanation
7 more videos on this problem
Choose K Elements With Maximum Sum | Brute Force | Optimal Leetcode 3478 | codestorywithMIKcodestorywithMIK · 40:57 · 7K views
3478. Choose K Elements With Maximum Sum | Sorting | Priority QueueAryan Mittal · 19:08 · 2K views
Day 69/90 |⚡🔥(LeetCode 3478) Choose K Elements With Maximum Sum | Heap Intuition🚀#8 #topkCTO Bhaiya · 55:27 · 462 views
3478. Choose K Elements With Maximum Sum (Leetcode Medium)Programming Live with Larry · 9:14 · 270 views
Choose K Elements With Maximum Sum (Leetcode Weekly 440)Soumya Bhattacharjee · 9:02 · 171 views
Leetcode 3478 | Choose K Elements With Maximum Sum | Weekly Contest 440Road To FAANG · 15:10 · 148 views
3478. Choose K Elements With Maximum Sum | Priority Queue | Sorting | LeetCode | Medium | O(NlogN)Leet's Code · 22:14 · 106 views
3478. Choose K Elements With Maximum Sum | Leetcode | Weekly Contest 440Amit Choraria · 17:00 · 67 views
The problem
You are given two integer arrays, nums1 and nums2, both of length n, along with a positive integer k.
For each index i from 0 to n - 1, perform the following:
- Find all indices
jwherenums1[j]is less thannums1[i]. - Choose at most
kvalues ofnums2[j]at these indices to maximize the total sum.
Return an array answer of size n, where answer[i] represents the result for the corresponding index i.
Example 1:
Input: nums1 = [4,2,1,5,3], nums2 = [10,20,30,40,50], k = 2
Output: [80,30,0,80,50]
Explanation:
- For
i = 0: Select the 2 largest values fromnums2at indices[1, 2, 4]wherenums1[j] < nums1[0], resulting in50 + 30 = 80. - For
i = 1: Select the 2 largest values fromnums2at index[2]wherenums1[j] < nums1[1], resulting in 30. - For
i = 2: No indices satisfynums1[j] < nums1[2], resulting in 0. - For
i = 3: Select the 2 largest values fromnums2at indices[0, 1, 2, 4]wherenums1[j] < nums1[3], resulting in50 + 30 = 80. - For
i = 4: Select the 2 largest values fromnums2at indices[1, 2]wherenums1[j] < nums1[4], resulting in30 + 20 = 50.
Example 2:
Input: nums1 = [2,2,2,2], nums2 = [3,1,2,3], k = 1
Output: [0,0,0,0]
Explanation:
Since all elements in nums1 are equal, no indices satisfy the condition nums1[j] < nums1[i] for any i, resulting in 0 for all positions.
Constraints:
n == nums1.length == nums2.length1 <= n <= 1051 <= nums1[i], nums2[i] <= 1061 <= k <= n
Approach overview
Problem Overview: You are given two arrays where each index represents a pair of values. For every position i, compute the maximum possible sum of up to k values from other indices whose first value is strictly smaller than nums1[i]. The goal is to efficiently track the best k candidates while scanning the array.
Approach 1: Brute Force with Heap per Index (O(n² log k) time, O(k) space)
For each index i, iterate through the entire array and collect elements where nums1[j] < nums1[i]. Maintain a min-heap of size at most k containing the largest nums2[j] values seen so far. Each candidate pushes into the heap and the smallest element is removed if the size exceeds k. The sum of the heap gives the best result for that index. This method is straightforward but expensive because the full scan repeats for every element.
Approach 2: Sorting + Priority Queue (Min-Heap) (O(n log n + n log k) time, O(n + k) space)
Sort indices by nums1 so elements with smaller values are processed first. As you iterate through the sorted order, maintain a running min-heap storing the largest k values from nums2 that have already been seen. Also track the current sum of the heap. For each group of indices with the same nums1 value, compute their answers using the current sum before inserting their nums2 values into the heap. This ensures only elements with strictly smaller nums1 contribute to the result. Each insertion or removal from the heap costs O(log k), keeping the overall runtime efficient.
The key insight: sorting transforms the "smaller value" condition into a prefix problem. Once elements are processed in increasing order, every previously visited element automatically satisfies the constraint.
This pattern appears frequently when combining sorting with incremental state tracking using a heap (priority queue). The input itself is just a standard array, but ordering it unlocks a much more efficient solution.
Recommended for interviews: The sorting + min-heap approach is the expected solution. It demonstrates recognition of ordering constraints and efficient top-k maintenance. Mentioning the brute force approach first shows you understand the problem space, but implementing the O(n log n + n log k) method proves strong algorithmic judgment.
Solution
We can convert the array nums1 into an array arr, where each element is a tuple (x, i), representing the value x at index i in nums1. Then, we sort the array arr in ascending order by x.
We use a min-heap pq to maintain the elements from the array nums2. Initially, pq is empty. We use a variable s to record the sum of the elements in pq. Additionally, we use a pointer j to maintain the current position in the array arr that needs to be added to pq.
We traverse the array arr. For the h-th element (x, i), we add all elements nums2[arr[j][1]] to pq that satisfy j < h and arr[j][0] < x, and add these elements to s. If the size of pq exceeds k, we pop the smallest element from pq and subtract it from s. Then, we update the value of ans[i] to s.
After traversing, we return the answer array ans.
The time complexity is O(n log n), and the space complexity is O(n). Here, n is the length of the array.
class Solution:
def findMaxSum(self, nums1: List[int], nums2: List[int], k: int) -> List[int]:
arr = [(x, i) for i, x in enumerate(nums1)]
arr.sort()
pq = []
s = j = 0
n = len(arr)
ans = [0] * n
for h, (x, i) in enumerate(arr):
while j < h and arr[j][0] < x:
y = nums2[arr[j][1]]
heappush(pq, y)
s += y
if len(pq) > k:
s -= heappop(pq)
j += 1
ans[i] = s
return ansclass Solution {
public long[] findMaxSum(int[] nums1, int[] nums2, int k) {
int n = nums1.length;
int[][] arr = new int[n][0];
for (int i = 0; i < n; ++i) {
arr[i] = new int[] {nums1[i], i};
}
Arrays.sort(arr, (a, b) -> a[0] - b[0]);
PriorityQueue<Integer> pq = new PriorityQueue<>();
long s = 0;
long[] ans = new long[n];
int j = 0;
for (int h = 0; h < n; ++h) {
int x = arr[h][0], i = arr[h][1];
while (j < h && arr[j][0] < x) {
int y = nums2[arr[j][1]];
pq.offer(y);
s += y;
if (pq.size() > k) {
s -= pq.poll();
}
++j;
}
ans[i] = s;
}
return ans;
}
}class Solution {
public:
vector<long long> findMaxSum(vector<int>& nums1, vector<int>& nums2, int k) {
int n = nums1.size();
vector<pair<int, int>> arr(n);
for (int i = 0; i < n; ++i) {
arr[i] = {nums1[i], i};
}
ranges::sort(arr);
priority_queue<int, vector<int>, greater<int>> pq;
long long s = 0;
int j = 0;
vector<long long> ans(n);
for (int h = 0; h < n; ++h) {
auto [x, i] = arr[h];
while (j < h && arr[j].first < x) {
int y = nums2[arr[j].second];
pq.push(y);
s += y;
if (pq.size() > k) {
s -= pq.top();
pq.pop();
}
++j;
}
ans[i] = s;
}
return ans;
}
};function findMaxSum(nums1: number[], nums2: number[], k: number): number[] {
const n = nums1.length;
const arr = nums1.map((x, i) => [x, i]).sort((a, b) => a[0] - b[0]);
const pq = new MinPriorityQueue<number>();
let [s, j] = [0, 0];
const ans: number[] = Array(k).fill(0);
for (let h = 0; h < n; ++h) {
const [x, i] = arr[h];
while (j < h && arr[j][0] < x) {
const y = nums2[arr[j++][1]];
pq.enqueue(y);
s += y;
if (pq.size() > k) {
s -= pq.dequeue();
}
}
ans[i] = s;
}
return ans;
}func findMaxSum(nums1 []int, nums2 []int, k int) []int64 {
n := len(nums1)
arr := make([][2]int, n)
for i, x := range nums1 {
arr[i] = [2]int{x, i}
}
ans := make([]int64, n)
sort.Slice(arr, func(i, j int) bool { return arr[i][0] < arr[j][0] })
pq := hp{}
var s int64
j := 0
for h, e := range arr {
x, i := e[0], e[1]
for j < h && arr[j][0] < x {
y := nums2[arr[j][1]]
heap.Push(&pq, y)
s += int64(y)
if pq.Len() > k {
s -= int64(heap.Pop(&pq).(int))
}
j++
}
ans[i] = s
}
return ans
}
type hp struct{ sort.IntSlice }
func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
func (h *hp) Pop() any {
a := h.IntSlice
v := a[len(a)-1]
h.IntSlice = a[:len(a)-1]
return v
}Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force with Heap per Index | O(n² log k) | O(k) | Useful for understanding the problem or when n is very small |
| Sorting + Min-Heap (Priority Queue) | O(n log n + n log k) | O(n + k) | Best general solution; efficiently maintains top k candidates while processing sorted elements |
Frequently asked questions
Is Choose K Elements With Maximum Sum easy or hard?
Choose K Elements With Maximum Sum is generally considered a medium difficulty problem. The challenge comes from recognizing that sorting converts the constraint into a prefix problem and that a heap can efficiently maintain the best k candidates.
Choose K Elements With Maximum Sum Python/Java solution
Most implementations follow the same structure: sort indices by nums1, iterate through them, maintain a min-heap of size k for nums2 values, and track a running sum. Python typically uses heapq, while Java implementations use PriorityQueue with O(log k) insertion and removal.
How to solve Choose K Elements With Maximum Sum efficiently?
Sort indices by nums1 so that all valid contributors appear before the current element. Maintain a running min-heap containing the largest k values from nums2 seen so far and track their sum. For each index, use the current heap sum as the answer before inserting its nums2 value into the heap.
What is the best approach for Choose K Elements With Maximum Sum?
The optimal solution sorts indices by the first array and processes them in increasing order while maintaining a min-heap of the largest k values from the second array. This allows efficient tracking of the best candidates that satisfy the "smaller value" condition. The time complexity is O(n log n + n log k) and space complexity is O(n + k).
Is Choose K Elements With Maximum Sum asked at Google/Amazon/Meta?
Problems combining sorting with heap-based top-k tracking frequently appear in interviews at companies like Amazon, Google, and Meta. Variants involving maintaining the k largest elements under ordering constraints are especially common in system design and algorithm screening rounds.
What data structure is used in Choose K Elements With Maximum Sum?
The core data structure is a min-heap (priority queue). It keeps the largest k values from nums2 while allowing efficient removal of the smallest when the heap exceeds size k. Sorting is also required to enforce the nums1 ordering constraint.
What is the time complexity of Choose K Elements With Maximum Sum?
The optimal algorithm runs in O(n log n + n log k). Sorting the indices by nums1 takes O(n log n), and each heap insertion or removal while maintaining the top k elements costs O(log k). Since each element is processed once, the total heap work is O(n log k).
