Prerequisites
Before attempting this problem, you should be comfortable with:
- Kadane's Algorithm - The optimized solutions use Kadane's algorithm to find maximum subarray sums
- Hash Maps - Used for tracking frequency counts and running sums for each value
- Subarray Problems - Understanding how to enumerate and process contiguous subarrays
1. Brute Force
Intuition
The operation lets us pick a subarray and add a constant to every element in it. Our goal is to maximize how often some value k appears. The key insight is that we want to convert elements of some value num into k by choosing the right constant. For each candidate num, we try every possible subarray, count how many num values we convert to k, and subtract any k values that get changed to something else within the subarray.
Algorithm
- Count how many times
kappears in the array (call itcntK). - For each possible value
numfrom1to50(excludingk):- For each starting index
i:- Reset the count and iterate through all ending indices
j. - Increment count when we see
num(it becomeskafter the operation). - Decrement
cntKwhen we seek(it changes to something else). - Track the maximum of
cntK + count.
- Reset the count and iterate through all ending indices
- For each starting index
- Return the maximum frequency found.
class Solution:
def maxFrequency(self, nums: List[int], k: int) -> int:
n = len(nums)
cntK = nums.count(k)
res = cntK
for num in range(1, 51):
if num == k: continue
for i in range(n):
tmp, cnt = cntK, 0
for j in range(i, n):
if nums[j] == num:
cnt += 1
elif nums[j] == k:
cntK -= 1
res = max(res, cnt + cntK)
cntK = tmp
return resTime & Space Complexity
- Time complexity:
- Space complexity:
2. Kadane's Algorithm - I
Intuition
The brute force tries all subarrays, but we can use Kadane's algorithm to find the best subarray in linear time. For a fixed target value num, we want to find a subarray where converting num to k gives the maximum net gain. Treat each num as +1 (we gain a k) and each k as -1 (we lose a k). Kadane's algorithm finds the maximum sum subarray, giving us the best gain for that target.
Algorithm
- Count how many times
kappears in the array (call itcntK). - For each possible value
ifrom1to50(excludingk):- Initialize
cnt = 0. - For each element in the array:
- Add
1if the element equalsi. - Subtract
1if the element equalsk. - Reset
cntto0if it goes negative (Kadane's reset). - Track the maximum of
cntK + cnt.
- Add
- Initialize
- Return the maximum frequency found.
class Solution:
def maxFrequency(self, nums: List[int], k: int) -> int:
cntK = nums.count(k)
res = 0
for i in range(1, 51):
if i == k:
continue
cnt = 0
for num in nums:
if num == i:
cnt += 1
if num == k:
cnt -= 1
cnt = max(cnt, 0)
res = max(res, cntK + cnt)
return resTime & Space Complexity
- Time complexity:
- Space complexity:
3. Kadane's Algorithm - II
Intuition
We can process all target values simultaneously in a single pass. For each number, we track the best running sum ending at the current position. When we see a number, its count can either extend from its previous best or start fresh from k's position (since we could start our subarray here). The maximum difference between any count and k's count represents the best gain achievable.
Algorithm
- Maintain a hash map
cntwherecnt[num]represents the best running sum ending at the current position for convertingnumtok. - For each element in the array:
- Update
cnt[num] = max(cnt[num], cnt[k]) + 1. - Track the maximum value of
cnt[num] - cnt[k].
- Update
- Return
cnt[k] + res, whereresis the maximum gain found.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Misunderstanding the Subarray Operation
The operation adds a constant to every element in a chosen subarray. A common mistake is to think you can selectively modify some elements within the subarray while leaving others unchanged. Every element in the range [l, r] gets the same constant added. This means if you have both k and num values in your chosen subarray, converting num to k will simultaneously change existing k values to something else.
Forgetting to Account for Lost k Values
When you apply the operation to a subarray to convert num values to k, any existing k values within that subarray become k + constant, which is no longer k. The net gain is (count of num in subarray) - (count of k in subarray). Solutions that only count the gains without subtracting the losses will produce incorrect results.
Not Resetting State Between Target Values
When iterating through all possible target values (1 to 50), each target requires its own independent Kadane's algorithm pass. Failing to reset the running count between targets will carry over state from previous iterations, leading to incorrect maximum subarray calculations. Initialize cnt = 0 at the start of each target value's iteration.
Ignoring the No-Operation Case
The operation is optional. Sometimes the best strategy is to not perform any operation at all, especially when k already appears frequently. The answer should always be at least count(k) in the original array. Some solutions focus so heavily on finding the best subarray that they forget to compare against the base case of leaving the array unchanged.
Applying the Wrong Kadane's Variant
Kadane's algorithm finds the maximum sum subarray, but the classic version requires at least one element. In this problem, an empty subarray (doing nothing to convert any num to k) is valid and contributes 0 to the gain. Solutions must allow the running sum to reset to 0 when it goes negative, representing the choice to not include those elements in the operation subarray.