Skip to content

Commit fa06981

Browse files
committed
Sync LeetCode submission Runtime - 3609 ms (37.93%), Memory - 45 MB (54.31%)
1 parent 6f96862 commit fa06981

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<p>You are given an array <code>nums</code> of <code>n</code> positive integers and an integer <code>k</code>.</p>
2+
3+
<p>Initially, you start with a score of <code>1</code>. You have to maximize your score by applying the following operation at most <code>k</code> times:</p>
4+
5+
<ul>
6+
<li>Choose any <strong>non-empty</strong> subarray <code>nums[l, ..., r]</code> that you haven&#39;t chosen previously.</li>
7+
<li>Choose an element <code>x</code> of <code>nums[l, ..., r]</code> with the highest <strong>prime score</strong>. If multiple such elements exist, choose the one with the smallest index.</li>
8+
<li>Multiply your score by <code>x</code>.</li>
9+
</ul>
10+
11+
<p>Here, <code>nums[l, ..., r]</code> denotes the subarray of <code>nums</code> starting at index <code>l</code> and ending at the index <code>r</code>, both ends being inclusive.</p>
12+
13+
<p>The <strong>prime score</strong> of an integer <code>x</code> is equal to the number of distinct prime factors of <code>x</code>. For example, the prime score of <code>300</code> is <code>3</code> since <code>300 = 2 * 2 * 3 * 5 * 5</code>.</p>
14+
15+
<p>Return <em>the <strong>maximum possible score</strong> after applying at most </em><code>k</code><em> operations</em>.</p>
16+
17+
<p>Since the answer may be large, return it modulo <code>10<sup>9 </sup>+ 7</code>.</p>
18+
19+
<p>&nbsp;</p>
20+
<p><strong class="example">Example 1:</strong></p>
21+
22+
<pre>
23+
<strong>Input:</strong> nums = [8,3,9,3,8], k = 2
24+
<strong>Output:</strong> 81
25+
<strong>Explanation:</strong> To get a score of 81, we can apply the following operations:
26+
- 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.
27+
- 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.
28+
It can be proven that 81 is the highest score one can obtain.</pre>
29+
30+
<p><strong class="example">Example 2:</strong></p>
31+
32+
<pre>
33+
<strong>Input:</strong> nums = [19,12,14,6,10,18], k = 3
34+
<strong>Output:</strong> 4788
35+
<strong>Explanation:</strong> To get a score of 4788, we can apply the following operations:
36+
- 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.
37+
- 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.
38+
- 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.
39+
It can be proven that 4788 is the highest score one can obtain.
40+
</pre>
41+
42+
<p>&nbsp;</p>
43+
<p><strong>Constraints:</strong></p>
44+
45+
<ul>
46+
<li><code>1 &lt;= nums.length == n &lt;= 10<sup>5</sup></code></li>
47+
<li><code>1 &lt;= nums[i] &lt;= 10<sup>5</sup></code></li>
48+
<li><code>1 &lt;= k &lt;= min(n * (n + 1) / 2, 10<sup>9</sup>)</code></li>
49+
</ul>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Approach 1: Monotonic Stack & Priority Queue
2+
3+
class Solution:
4+
MOD = 10**9 + 7
5+
6+
def maximumScore(self, nums, k):
7+
n = len(nums)
8+
prime_scores = [0] * n
9+
10+
# Calculate the prime score for each number in nums
11+
for index in range(n):
12+
num = nums[index]
13+
14+
# Check for prime factors from 2 to sqrt(n)
15+
for factor in range(2, int(math.sqrt(num)) + 1):
16+
if num % factor == 0:
17+
# Increment prime score for each prime factor
18+
prime_scores[index] += 1
19+
20+
# Remove all occurrences of the prime factor from num
21+
while num % factor == 0:
22+
num //= factor
23+
24+
# If num is still greater than or equal to 2, it's a prime factor
25+
if num >= 2:
26+
prime_scores[index] += 1
27+
28+
# Initialize next and previous dominant index arrays
29+
next_dominant = [n] * n
30+
prev_dominant = [-1] * n
31+
32+
# Stack to store indices for monotonic decreasing prime score
33+
decreasing_prime_score_stack = []
34+
35+
# Calculate the next and previous dominant indices for each number
36+
for index in range(n):
37+
# While the stack is not empty and the current prime score is greater than the stack's top
38+
while (
39+
decreasing_prime_score_stack
40+
and prime_scores[decreasing_prime_score_stack[-1]]
41+
< prime_scores[index]
42+
):
43+
top_index = decreasing_prime_score_stack.pop()
44+
45+
# Set the next dominant element for the popped index
46+
next_dominant[top_index] = index
47+
48+
# If the stack is not empty, set the previous dominant element for the current index
49+
if decreasing_prime_score_stack:
50+
prev_dominant[index] = decreasing_prime_score_stack[-1]
51+
52+
# Push the current index onto the stack
53+
decreasing_prime_score_stack.append(index)
54+
55+
# Calculate the number of subarrays in which each element is dominant
56+
num_of_subarrays = [0] * n
57+
for index in range(n):
58+
num_of_subarrays[index] = (next_dominant[index] - index) * (
59+
index - prev_dominant[index]
60+
)
61+
62+
# Priority queue to process elements in decreasing order of their value
63+
processing_queue = []
64+
65+
# Push each number and its index onto the priority queue
66+
for index in range(n):
67+
heapq.heappush(processing_queue, (-nums[index], index))
68+
69+
score = 1
70+
71+
# Helper function to compute the power of a number modulo MOD
72+
def _power(base, exponent):
73+
res = 1
74+
75+
# Calculate the exponentiation using binary exponentiation
76+
while exponent > 0:
77+
# If the exponent is odd, multiply the result by the base
78+
if exponent % 2 == 1:
79+
res = (res * base) % self.MOD
80+
81+
# Square the base and halve the exponent
82+
base = (base * base) % self.MOD
83+
exponent //= 2
84+
85+
return res
86+
87+
# Process elements while there are operations left
88+
while k > 0:
89+
# Get the element with the maximum value from the queue
90+
num, index = heapq.heappop(processing_queue)
91+
num = -num # Negate back to positive
92+
93+
# Calculate the number of operations to apply on the current element
94+
operations = min(k, num_of_subarrays[index])
95+
96+
# Update the score by raising the element to the power of operations
97+
score = (score * _power(num, operations)) % self.MOD
98+
99+
# Reduce the remaining operations count
100+
k -= operations
101+
102+
return score

0 commit comments

Comments
 (0)