diff --git a/puzzles/heap/__init__.py b/puzzles/heap/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/puzzles/heap/maximum_subsequence_score/README.md b/puzzles/heap/maximum_subsequence_score/README.md new file mode 100644 index 00000000..40bf820e --- /dev/null +++ b/puzzles/heap/maximum_subsequence_score/README.md @@ -0,0 +1,41 @@ +# Maximum Subsequence Score + +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 nums1 multiplied with the minimum of the selected elements from nums2. +It can be 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. + +```plain +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. +``` + +## Related Topics + +- Array +- Greedy +- Sorting +- Heap (Priority Queue) diff --git a/puzzles/heap/maximum_subsequence_score/__init__.py b/puzzles/heap/maximum_subsequence_score/__init__.py new file mode 100644 index 00000000..ba113b0c --- /dev/null +++ b/puzzles/heap/maximum_subsequence_score/__init__.py @@ -0,0 +1,17 @@ +from typing import List +from heapq import heappush, heappop +from operator import itemgetter + + +def max_score(nums1: List[int], nums2: List[int], k: int) -> int: + result, total_sum, min_heap = 0, 0, [] + merged = sorted(list(zip(nums1, nums2)), key=itemgetter(1), reverse=True) + + for num_1_value, max_of_2 in merged: + total_sum += num_1_value + heappush(min_heap, num_1_value) + if len(min_heap) == k: + result = max(result, total_sum * max_of_2) + total_sum -= heappop(min_heap) + + return result diff --git a/puzzles/heap/maximum_subsequence_score/test_max_subsequence_score.py b/puzzles/heap/maximum_subsequence_score/test_max_subsequence_score.py new file mode 100644 index 00000000..75253a28 --- /dev/null +++ b/puzzles/heap/maximum_subsequence_score/test_max_subsequence_score.py @@ -0,0 +1,27 @@ +import unittest + +from . import max_score + + +class MaxSubsequenceScoreTestCase(unittest.TestCase): + def test_1(self): + """nums1 = [1,3,3,2], nums2 = [2,1,3,4], k = 3 returns 12""" + nums1 = [1, 3, 3, 2] + nums2 = [2, 1, 3, 4] + k = 3 + expected = 12 + actual = max_score(nums1, nums2, k) + self.assertEqual(expected, actual) + + def test_2(self): + """nums1 = [4,2,3,1,1], nums2 = [7,5,10,9,6], k = 1 returns 30""" + nums1 = [4, 2, 3, 1, 1] + nums2 = [7, 5, 10, 9, 6] + k = 1 + expected = 30 + actual = max_score(nums1, nums2, k) + self.assertEqual(expected, actual) + + +if __name__ == '__main__': + unittest.main()