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:

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:

Input: nums = [8,3,9,3,8], k = 2
Output: 81
Explanation: To get a score of 81, we can apply the following operations:
- Choose subarray nums[2, ..., 2]. nums[2] is the only element in this subarray. Hence, we multiply the score by nums[2]. The score becomes 1 * 9 = 9.
- Choose subarray nums[2, ..., 3]. Both nums[2] and nums[3] have a prime score of 1, but nums[2] has the smaller index. Hence, we multiply the score by nums[2]. The score becomes 9 * 9 = 81.
It can be proven that 81 is the highest score one can obtain.

Example 2:

Input: nums = [19,12,14,6,10,18], k = 3
Output: 4788
Explanation: To get a score of 4788, we can apply the following operations: 
- Choose subarray nums[0, ..., 0]. nums[0] is the only element in this subarray. Hence, we multiply the score by nums[0]. The score becomes 1 * 19 = 19.
- Choose subarray nums[5, ..., 5]. nums[5] is the only element in this subarray. Hence, we multiply the score by nums[5]. The score becomes 19 * 18 = 342.
- Choose subarray nums[2, ..., 3]. Both nums[2] and nums[3] have a prime score of 2, but nums[2] has the smaller index. Hence, we multipy the score by nums[2]. The score becomes 342 * 14 = 4788.
It can be proven that 4788 is the highest score one can obtain.

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:

2 Compute Next Greater Elements:

3 Sort and Process Elements:

4 Helper Function for Exponentiation:

Complexity

Code (Swift)

class Solution {

    func maximumScore(_ nums: [Int], _ k: Int) -> Int {
        let MOD = 1_000_000_007
        var k = k  // Make a mutable copy of k
        let n = nums.count

        var upper = nums.max()! + 1

        var prime = [Bool](repeating: true, count: upper)
        prime[0] = false
        prime[1] = false
        var primeScore = [Int](repeating: 0, count: upper)

        for i in 2..<upper {
            if prime[i] {
                var j = i
                while j < upper {
                    primeScore[j] += 1
                    prime[j] = false
                    j += i
                }
            }
        }

        var nextGreaterElement = [Int](repeating: n, count: n)
        var s = [Int]()
        for i in (0..<n).reversed() {
            while !s.isEmpty && primeScore[nums[i]] >= primeScore[nums[s.last!]] {
                s.popLast()
            }
            nextGreaterElement[i] = s.isEmpty ? n : s.last!
            s.append(i)
        }

        var prevGreaterOrEqualElement = [Int](repeating: -1, count: n)
        s.removeAll()
        for i in 0..<n {
            while !s.isEmpty && primeScore[nums[i]] > primeScore[nums[s.last!]] {
                s.popLast()
            }
            prevGreaterOrEqualElement[i] = s.isEmpty ? -1 : s.last!
            s.append(i)
        }

        var res = 1
        var tuples = [(num: Int, index: Int)]()
        for i in 0..<n {
            tuples.append((nums[i], i))
        }
        tuples.sort { a, b in
            a.num > b.num
        }

        for (num, i) in tuples {
            let operations = min(
                (i - prevGreaterOrEqualElement[i]) * (nextGreaterElement[i] - i), k)
            res = (res * pow(num, operations, MOD)) % MOD
            k -= operations
            if k == 0 {
                return res
            }
        }

        return res
    }

    func pow(_ x: Int, _ n: Int, _ mod: Int) -> Int {
        var res = 1
        var x = x
        var n = n
        while n > 0 {
            if n % 2 == 1 {
                res = (res * x) % mod
            }
            x = (x * x) % mod
            n /= 2
        }
        return res
    }
}

Source: Github

@Leschev
19.08.2023 22:09 UTC
Первоисточник

Комментарии

@Nurked
20.08.2023 04:35 UTC
0

А чёэто-то? Я чёт пропустил? За перепощивание на хабре Гитхаба теперь грамоту дають?

Хотя, если вам хочется сделать из этого хорошую статью - непишите в личку. Я помогу.