Maximum Subsequence Score solution and explanation
9 more videos on this problem
Maximum Subsequence Score - Leetcode 2542 - PythonNeetCodeIO · 13:59 · 34K views
Maximum Subsequence Score | Intuition | AMAZON | Leetcode-2542 | Explanation ➕ Live CodingcodestorywithMIK · 41:48 · 16K views
2542. Maximum Subsequence Score | Leetcode BiWeekly Contest 96Tech Courses · 12:53 · 4K views
Maximum Subsequence Score | Biweekly Contest 96 | LeetcodecodingMohan · 26:04 · 3K views
2542. Maximum Subsequence Score | LeetCode Daily ChallengeDeep Tech · 21:31 · 2K views
Maximum Subsequence Score - Leetcode 2542 - PythonTechError · 7:41 · 1K views
2542. Maximum Subsequence Score (Leetcode Medium)Programming Live with Larry · 12:00 · 1K views
Maximum Subsequence Score #leetcode #leetcode75 #interviewquestionsDeepti Talesra · 15:26 · 1K views
LeetCode Biweekly Contest 96 | 2542 : Maximum Subsequence Score Solution | Newton SchoolFly with Coding | Newton School · 17:24 · 1K views
2542 || Maximum Subsequence Score || C++ || Leetcode Daily ChallengeCodeFreaks · 20:40 · 912 views
The problem
You are given two 0-indexed integer arrays nums1 and nums2 of equal length n and a positive integer k. You must choose a subsequence of indices from nums1 of length k.
For chosen indices i0, i1, ..., ik - 1, your score is defined as:
- The sum of the selected elements from
nums1multiplied with the minimum of the selected elements fromnums2. - It can defined simply as:
(nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] , nums2[i1], ... ,nums2[ik - 1]).
Return the maximum possible score.
A subsequence of indices of an array is a set that can be derived from the set {0, 1, ..., n-1} by deleting some or no elements.
Example 1:
Input: nums1 = [1,3,3,2], nums2 = [2,1,3,4], k = 3 Output: 12 Explanation: The four possible subsequence scores are: - We choose the indices 0, 1, and 2 with score = (1+3+3) * min(2,1,3) = 7. - We choose the indices 0, 1, and 3 with score = (1+3+2) * min(2,1,4) = 6. - We choose the indices 0, 2, and 3 with score = (1+3+2) * min(2,3,4) = 12. - We choose the indices 1, 2, and 3 with score = (3+3+2) * min(1,3,4) = 8. Therefore, we return the max score, which is 12.
Example 2:
Input: nums1 = [4,2,3,1,1], nums2 = [7,5,10,9,6], k = 1 Output: 30 Explanation: Choosing index 2 is optimal: nums1[2] * nums2[2] = 3 * 10 = 30 is the maximum possible score.
Constraints:
n == nums1.length == nums2.length1 <= n <= 1050 <= nums1[i], nums2[j] <= 1051 <= k <= n
Approach overview
Problem Overview: You are given two arrays nums1 and nums2 and an integer k. Choose exactly k indices such that the score (sum of selected nums1) * (minimum selected nums2) is maximized. The challenge is balancing a large sum from nums1 while keeping the minimum value from nums2 as high as possible.
Approach 1: Sorting with Priority Queue (O(n log n) time, O(k) space)
The key observation: if a value from nums2 becomes the minimum of the chosen subsequence, then every other selected element must have nums2 greater than or equal to it. Sort pairs (nums1[i], nums2[i]) in descending order of nums2. As you iterate, treat the current nums2 as the minimum candidate. Maintain a min-heap of the largest k values from nums1 and track their running sum. Each time the heap reaches size k, compute the score using the current nums2. The heap ensures you always keep the best k contributors to the sum while iterating through decreasing minimum values. This approach combines sorting, greedy selection, and a priority queue to efficiently explore all valid minimum candidates.
Approach 2: Divide and Conquer (Optimal Subsequence Selection) (O(n log n) time, O(n) space)
Another way to think about the problem is recursively splitting the candidate range of indices after sorting by nums2. Each segment represents a potential range where a specific nums2 value acts as the minimum. Within each segment, select the best k contributors from nums1 and propagate partial results upward. The divide-and-conquer structure reduces repeated work by reusing partial sums and candidate sets across recursive segments. While the complexity remains O(n log n), this approach is useful when implementing language-specific optimizations or when integrating with segment-based selection techniques.
Recommended for interviews: The sorting + priority queue solution is the expected answer. It demonstrates strong algorithmic intuition: reduce the problem by fixing the minimum nums2, then greedily maximize the sum using a heap. Interviewers typically want to see the insight that sorting by nums2 converts the "minimum constraint" into a linear scan.
Approach 1: Sorting with Priority Queue
In this approach, the idea is to pair up elements of nums1 and nums2 into tuples. Then, sort these pairs by nums2 in descending order. This way, we process elements with higher values in nums2 first. Using a priority queue (min-heap), we can efficiently keep track of the k largest nums1 values, which we use to calculate the score. The maximum score is computed by iterating through potential minimums, maintaining the current sum of the largest k values seen so far.
import heapq
def maxScore(nums1, nums2, k):
pairs = sorted(zip(nums2, nums1), reverse=True)
min_heap = []
current_sum = 0
max_score = 0
for num2, num1 in pairs:
heapq.heappush(min_heap, num1)
current_sum += num1
if len(min_heap) > k:
current_sum -= heapq.heappop(min_heap)
if len(min_heap) == k:
max_score = max(max_score, current_sum * num2)
return max_score
# Example usage
print(maxScore([1,3,3,2], [2,1,3,4], 3)) # Output: 12#include <vector>
#include <queue>
#include <algorithm>
int maxScore(std::vector<int>& nums1, std::vector<int>& nums2, int k) {
std::vector<std::pair<int, int>> pairs;
for (size_t i = 0; i < nums1.size(); ++i) {
pairs.emplace_back(nums2[i], nums1[i]);
}
std::sort(pairs.rbegin(), pairs.rend());
std::priority_queue<int, std::vector<int>, std::greater<>> min_heap;
long long current_sum = 0, max_score = 0;
for (const auto& [num2, num1] : pairs) {
min_heap.push(num1);
current_sum += num1;
if (min_heap.size() > k) {
current_sum -= min_heap.top();
min_heap.pop();
}
if (min_heap.size() == k) {
max_score = std::max(max_score, current_sum * num2);
}
}
return max_score;
}
// Example usage
// std::cout << maxScore({1,3,3,2}, {2,1,3,4}, 3) << std::endl; // Output: 12The solution sorts nums2 together with nums1. It processes from the largest nums2 value, maintaining a sum and a priority queue to track the largest k values of nums1. The score is calculated as the product of this sum and the current nums2 value in the loop, updating the maximum score as needed.
Time Complexity: O(n log n) due to sorting and heap operations.
Space Complexity: O(k) for the min-heap storing k elements.
Approach 2: Divide and Conquer (Optimal Subsequence Selection)
This approach emphasizes efficient subsequence selection by partitioning the array. Divide the array in such a way that potential results can be directly computed without redundant calculations. Use recursion to evaluate possible subsequences efficiently.
import java.util.*;
public class Solution {
public int maxScore(int[] nums1, int[] nums2, int k) {
List<int[]> pairs = new ArrayList<>();
for (int i = 0; i < nums1.length; ++i) {
pairs.add(new int[]{nums2[i], nums1[i]});
}
pairs.sort((a, b) -> Integer.compare(b[0], a[0]));
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
long currentSum = 0, maxScore = 0;
for (int[] pair : pairs) {
int num2 = pair[0], num1 = pair[1];
minHeap.add(num1);
currentSum += num1;
if (minHeap.size() > k) {
currentSum -= minHeap.poll();
}
if (minHeap.size() == k) {
maxScore = Math.max(maxScore, currentSum * num2);
}
}
return (int) maxScore;
}
// Example usage
// public static void main(String[] args) {
// System.out.println(new Solution().maxScore(new int[]{1,3,3,2}, new int[]{2,1,3,4}, 3)); // Output: 12
// }
}function maxScore(nums1, nums2, k) {
const pairs = nums1.map((num1, i) => [nums2[i], num1]).sort((a, b) => b[0] - a[0]);
const minHeap = [];
let currentSum = 0, maxScore = 0;
for (let [num2, num1] of pairs) {
minHeap.push(num1);
currentSum += num1;
if (minHeap.length > k) {
currentSum -= Math.min(...minHeap);
minHeap.splice(minHeap.indexOf(Math.min(...minHeap)), 1);
}
if (minHeap.length === k) {
maxScore = Math.max(maxScore, currentSum * num2);
}
}
return maxScore;
}
// Example usage
// console.log(maxScore([1,3,3,2], [2,1,3,4], 3)); // Output: 12The Java implementation uses List to manage pairs and utilizes the built-in sorting method for ordering. It implements similar logic using priority queues to track k largest elements for scoring.
Time Complexity: O(n log n) primary by sorting and heap operations.
Space Complexity: O(k) for the priority queue.
Approach 3: Sorting + Priority Queue (Min Heap)
Sort nums2 and nums1 in descending order according to nums2, then traverse from front to back, maintaining a min heap. The heap stores elements from nums1, and the number of elements in the heap does not exceed k. At the same time, maintain a variable s representing the sum of the elements in the heap, and continuously update the answer during the traversal process.
The time complexity is O(n times log n), and the space complexity is O(n). Here, n is the length of the array nums1.
func maxScore(nums1 []int, nums2 []int, k int) int64 {
type pair struct{ a, b int }
nums := []pair{}
for i, a := range nums1 {
b := nums2[i]
nums = append(nums, pair{a, b})
}
sort.Slice(nums, func(i, j int) bool { return nums[i].b > nums[j].b })
q := hp{}
var ans, s int
for _, e := range nums {
a, b := e.a, e.b
s += a
heap.Push(&q, a)
if q.Len() == k {
ans = max(ans, s*b)
s -= heap.Pop(&q).(int)
}
}
return int64(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 comparison
| Approach | Complexity |
|---|---|
| Sorting with Priority Queue | Time Complexity: O(n log n) due to sorting and heap operations. |
| Divide and Conquer (Optimal Subsequence Selection) | Time Complexity: O(n log n) primary by sorting and heap operations. |
| Sorting + Priority Queue (Min Heap) | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Sorting with Priority Queue | O(n log n) | O(k) | General optimal solution; standard interview approach combining sorting and heap |
| Divide and Conquer Subsequence Selection | O(n log n) | O(n) | Useful for recursive or segment-based implementations where candidate ranges are processed independently |
Frequently asked questions
Is Maximum Subsequence Score easy or hard?
Maximum Subsequence Score is rated Medium difficulty on LeetCode. The implementation is straightforward once the greedy insight is discovered, but identifying that sorting by nums2 converts the minimum constraint into a manageable iteration is the main challenge.
Maximum Subsequence Score Python/Java solution
In Python, the solution typically uses heapq as a min-heap while iterating over sorted pairs. Java implementations use PriorityQueue with the same logic. Both follow the pattern of sorting by nums2, maintaining k nums1 values, and updating the best score.
How to solve Maximum Subsequence Score in O(n)?
An O(n) solution is generally not feasible because the algorithm must consider ordering by nums2 values. Sorting the elements is necessary to evaluate candidates for the minimum multiplier, which introduces an O(n log n) lower bound in typical implementations.
What is the best approach for Maximum Subsequence Score?
The optimal approach sorts pairs by nums2 in descending order and uses a min-heap to maintain the k largest nums1 values seen so far. For each candidate minimum nums2, compute the score using the current sum of the heap. This greedy + priority queue strategy runs in O(n log n) time and O(k) space.
Is Maximum Subsequence Score asked at Google/Amazon/Meta?
Greedy problems involving heaps, sorting, and subsequence selection are common in interviews at companies like Google, Amazon, and Meta. This problem specifically tests the ability to transform a minimum constraint into a sorted greedy scan with a priority queue.
What data structure is used in Maximum Subsequence Score?
A min-heap (priority queue) is the core data structure. It keeps track of the k largest nums1 values while iterating through elements sorted by nums2. This allows efficient updates to the running sum used to compute the score.
What is the time complexity of Maximum Subsequence Score?
The optimal solution runs in O(n log n) time due to sorting the pairs and performing heap operations while scanning the array. The heap size is limited to k, so each insertion or removal costs O(log k). Space complexity is O(k).
