Problem
You've given an integer array nums and integer k. Find the maximum subarray sum of all the subarraay of nums that meet the following conditions.
- The length of the subarray is k, and
- All the elements of the subarray are distinct.
If no subarray meets the conditions, return 0.
Thought process
Keep a flag to know when its sure to compare. Update the flag to false when theres multiple frequencies using a dict. The issue is that if there are multiple discrepencies then i dont know when to turn back the flag to true? I am a little lost on that. Any idea would help me. Specifically i can't pass the third case in the tests.
Code
class Solution:
def maximumSubarraySum(self, a, k):
sumSoFar, toReturn, i, j = 0, 0, 0, 0
canIcount = True
eleToFreq = dict()
N = len(a)
if len(set(a)) < k: # Handle all-duplicate case
return 0
while j < N:
if j >= k - 1:
if a[j] in eleToFreq:
eleToFreq[a[j]] += 1
canIcount = False
else:
eleToFreq[a[j]] = 1
sumSoFar += a[j]
if canIcount:
toReturn = max(toReturn, sumSoFar)
#print('does ' , eleToFreq, ' have ', a[i])
if eleToFreq[a[i]] >= 1:
eleToFreq[a[i]] -= 1
else:
eleToFreq.pop(a[i])
sumSoFar-=a[i]
i+=1
j+=1
else:
if a[j] in eleToFreq:
eleToFreq[a[j]] += 1
canIcount = False
else:
eleToFreq[a[j]] = 1
sumSoFar += a[j]
j+=1
return toReturn
solution = Solution()
arr = [1, 5, 4, 2, 9, 9, 9]
k = 3
a = solution.maximumSubarraySum(arr, k)
print("Output:", a)
# Expected output: 15 actual output: 15
arr = [4, 4, 4]
k = 3
a = solution.maximumSubarraySum(arr, k)
print("Output:", a)
# Expected output: 0 actual output: 0
arr = [1,1,1,7,8,9]
k = 3
a = solution.maximumSubarraySum(arr, k)
print("Output:", a)
# Expected output: 24 actual output:0
Your flag
canIcountwould need to be set to true again when all values in the current window are unique. This happens when the count of distinct values in the window isk, in other words when the number of keys in your dictionary isk. And as Kelly pointed out in comments this means you can do without that flag, and just checklen(eleToFreq) == k.Another issue is the condition
eleToFreq[a[i]] >= 1, which should beeleToFreq[a[i]] > 1as in the other case you'd want to pop the entry.With those two things adapted with minimal changes to your code, we get this working code:
Remarks on your code
There is some duplication of code in the
ifandelseblocks which you can easily avoid by moving it out of there.As you increment
jconsistently in each iteration, it is more pythonic to use afor..inloop, and in this case it is useful to useenumerateso that you don't needNeither.Instead of tuple assignment for initialising several variables to 0, you could chain the assignment and use a single 0.
It is not necessary to deal separately with the case where the number of unique items in the input is less than
k. The main loop will deal with this, and so you avoid the work of creating asetof the input.That leads to this code:
You could reduce the code more by using
defaultdict, but it will not improve the performance.