LeetCode, Hard: 2818. Apply Operations to Maximize Score. Swift
Description
You are given an array nums of n positive integers and an integer k.
Initially, you start with a score of 1. You have to maximize your score by applying the following operation at most k times:
- Choose any non-empty subarray nums[l, ..., r] that you haven't chosen previously.
- Choose an element x of nums[l, ..., r] with the highest prime score. If multiple such elements exist, choose the one with the smallest index.
- Multiply your score by x.
Here, nums[l, ..., r] denotes the subarray of nums starting at index l and ending at the index r, both ends being inclusive.
The prime score of an integer x is equal to the number of distinct prime factors of x. For example, the prime score of 300 is 3 since 300 = 2 * 2 * 3 * 5 * 5.
Return the maximum possible score after applying at most k operations.
Since the answer may be large, return it modulo 10^9 + 7.
Example 1:
Example 2:
Constraints:
1 <= nums.length == n <= 10^5
1 <= nums[i] <= 10^5
1 <= k <= min(n * (n + 1) / 2, 10^9)
Approach
1 Compute Prime Scores:
- Calculate the prime score for each integer in the array nums. Prime score represents the number of distinct prime factors of an integer.
- Initialize a boolean array prime of size upper, where upper is the maximum element in nums plus 1.
- Initialize an integer array primeScore of the same size.
- Set prime[0] and prime[1] to false.
- Iterate over integers from 2 to upper - 1, and update primeScore and prime based on their prime factors.
2 Compute Next Greater Elements:
- Initialize arrays nextGreaterElement and prevGreaterOrEqualElement of size n, where n is the length of nums.
- Use a monotonic stack to find the next greater element with a greater prime score for each element in nums.
- Iterate through nums and maintain a stack of indices.
- For each element, pop elements from the stack if their prime score is less than or equal to the current element's prime score.
- Record the index of the top of the stack as the nextGreaterElement if the stack is not empty, else set it to n.
- Repeat the above process in reverse to compute prevGreaterOrEqualElement.
3 Sort and Process Elements:
- Create an array of tuples (num, i) where num is the value of an element and i is its index in nums.
- Sort the tuples in descending order of the first element (num).
- Loop through the sorted tuples and perform the following steps:Compute the number of operations as the minimum of (i - prevGreaterOrEqualElement[i]) * (nextGreaterElement[i] - i) and k.Update res by multiplying it with pow(num, operations) modulo MOD using the helper function pow.Decrement k by the number of operations.If k becomes 0, return res.
4 Helper Function for Exponentiation:
- Implement the pow function to calculate exponentiation efficiently using modular arithmetic.
Complexity
- Time complexity: O(max(nums) * log(max(nums)) + n * log(n)). Accounting for computing prime scores, using the stack to compute next greater elements, and sorting the tuples.
- Space complexity: O(max(nums) + n). Considering the space required for arrays and the stack used for computation.
Code (Swift)
Source: Github