2444. Count Subarrays With Fixed Bounds
class Solution:
def countSubarrays(self, nums: List[int], minK: int, maxK: int) -> int:
'''
https://leetcode.com/problems/count-subarrays-with-fixed-bounds/solutions/2708099/java-c-python-sliding-window-with-explanation/
We maintain a maximum sliding window
with alll elements in range [minK, maxK],
For all A[i] as rightmost element of the subarray,
we find the three indices j, where:
jbad is index of last seen A[jbad] < minK || A[jbad] > maxK
jmin is index of last seen A[jmin] = mink
jmax is index of last seen A[jmax] = maxk
Itearte the A[i],
if A[i] < minK || A[i] > maxK, update jbad = i.
if A[i] == minK, update jmin = i.
if A[i] == maxK, update jmax = i.
In the end of each iteration,
the subarray ends at A[i]
the starting element of the subarray,
can be choosen in interval [jbad + 1, min(jmin, jmax)]
There are min(jmin, jmax) - jbad choices,
so we update res += max(0, min(jmin, jmax) - jbad).
'''
jbad = jmin = jmax = -1
re = 0
for i, a in enumerate(nums):
if not minK <= a <= maxK:
jbad = i
if a == minK:
jmin = i
if a == maxK:
jmax= i
re += max(0, min(jmin, jmax) - jbad)
return re
2134. Minimum Swaps to Group All 1's Together II
class Solution:
def minSwaps(self, nums: List[int]) -> int:
# sliding window, count # of 1 say x, then check x window size and see how many swaps need
c = sum(nums)
nums += nums
s = sum(nums[:c]) # first window sum
re = c - s
for i in range(1, len(nums) - c):
s = s + nums[i+c-1] - nums[i-1] # add right, remove left
re = min(re, c - s)
return re
930. Binary Subarrays With Sum
class Solution:
def numSubarraysWithSum(self, nums: List[int], S: int) -> int:
def atMost(S): # number of subarrays add up to at most S
print("ssss", S)
if S < 0: return 0
res = i = 0
for j in range(len(nums)):
S -= nums[j]
while S < 0:
S += nums[i]
i += 1
res += j - i + 1 # 这个lenght 里面的 end with j 的subarry 有几个
# print("i,j", i, j, "".join(map(str, nums))[i:j+1])
# print("res", res)
return res
return atMost(S) - atMost(S - 1)
'''
c = collections.Counter({0: 1})
psum = res = 0
for i in nums:
# print("----")
# print("i", i)
psum += i
# print("presum", psum)
# print("presum-S", psum-S)
res += c[psum - S] # ex1 找后面的 0101,相当于找前面的1
# print("res", res)
c[psum] += 1
return res
'''
1248. Count Number of Nice Subarrays
class Solution:
def numberOfSubarrays(self, nums: List[int], k: int) -> int:
re = count = i = 0
idx = [] # index of the odd numbers
for j, v in enumerate(nums):
if v & 1:
count += 1
idx.append(j)
while count > k:
if nums[i] & 1:
count -= 1
idx.pop(0)
i += 1
if count == k:
re += idx[0] - i + 1
return re
i = count = res = 0
for j in xrange(len(A)):
if A[j] & 1:
k -= 1
count = 0
while k == 0:
k += A[i] & 1
i += 1
count += 1 # 类似于上面的解法 count [idx[0]-i+1] 但是 这个是 k==0的时候, 满足情况的时候,就开始count
res += count
return res
1358. Number of Substrings Containing All Three Characters
class Solution:
def numberOfSubstrings(self, s: str) -> int:
count = {c:0 for c in "abc"}
res = i = 0
for j, c in enumerate(s):
count[c] += 1
while all(count.values()):
count[s[i]] -= 1
i += 1
res += i
return res
'''
Time O(N) Space O(1)
res += i
This is the best line ever
0 1 2 3 4 5 6 7 8 9
a a a b b c c a b c
when all a, b, c > 0 for first time at j = 5 the n after while loop i will be at i = 3, we will add 3 to result because there would be three substrings from three a's.
Then a,b,c > 0 at j = 7 ,then we will move i until i = 5 then we will add 5 to result because there could be 5 substrings starting from 0 to second b.
And similarly we proceed....
'''
'''
和上面的解法思路一样, 只不过用last 来存 3个char的位置, 1+min(last)=0 的话代表还有char没找到
res, last = 0, [-1] * 3
for i, c in enumerate(s):
last[ord(c) - 97] = i
res += 1 + min(last)
return res
'''
1838. Frequency of the Most Frequent Element
class Solution:
def maxFrequency(self, A: List[int], k: int) -> int:
'''
https://leetcode.com/problems/frequency-of-the-most-frequent-element/solutions/1175090/java-c-python-sliding-window/
Sort the input array A
Sliding window prolem actually,
the key is to find out the valid condition:
k + sum >= size * max
which is
k + sum >= (j - i + 1) * A[j]
'''
i = 0
A.sort()
s = k
for j in range(len(A)):
s += A[j]
if s < (j - i + 1) * A[j]:
s -= A[i]
i += 1
return j - i + 1
424. Longest Repeating Character Replacement
class Solution:
def characterReplacement(self, s: str, k: int) -> int:
# 2 pointers, 总长度 - 出现最多的字母的频率 要小于等于K 否则就要移动left pointer
'''
The reason behind why it is fine to not update mostFreqLetter:
consider aaaabccc and k = 1
1st max we find is 5 (aaaab). mostFreqLetter is 4 (a). However once c rolls over in the window mostFreqLetter is no longer 4. But it doesn't matter because you can't find another substring (bccc) that is longer than the current longest substring (aaaab). However, if hypothetically the input string were aaaabccccc, then mostFreqLetter would become 5 (c in bccccc) and max would be updated to 6.
'''
l = 0
count = collections.defaultdict(int)
maxFreq = 0
re = 0
for r in range(len(s)):
c = s[r]
count[c] += 1
maxFreq = max(maxFreq, count[c])
print(r, l, maxFreq, k, c, r - l + 1 - maxFreq > k)
if r - l + 1 - maxFreq > k:
count[s[l]] -= 1
l += 1
re = max(re, r-l+1)
print(re)
return re
1658. Minimum Operations to Reduce X to Zero
class Solution:
def minOperations(self, nums: List[int], x: int) -> int:
# 方法1 preSum, suffic Sum 然后按照two sum的做法 但是要至少3 或者2个pass 已经O(n) space
# 方法2 先求整个的sum, 左右指针都是0, 然后右指针像右移动, sum- 左边的数字, 如果sum 小于x, 左指针再像右移动 O(1) space
n = len(nums)
s = sum(nums)
if s == x: return n
l = 0
re = n
for r in range(n):
s -= nums[r]
while s < x and l < r:
s += nums[l]
l += 1
if s == x:
re = min(re, n - (r - l + 1))
return re if re < n else -1
1493. Longest Subarray of 1's After Deleting One Element
class Solution:
def longestSubarray(self, nums: List[int]) -> int:
# sliding window
# i, j 代表 windown的 left, right boundary
# sum window, 因为都是1, 最大的sum 就是i-j+1。 如果有一个是0, sum就是i-j。 如果超过1个0, sum < i-j 则需要不断pop left元素
i = 0
re = _sum = 0
for j, n in enumerate(nums):
_sum += n
while _sum < j - i:
_sum -= nums[i]
i += 1
re = max(re, _sum)
return re - 1 if len(nums) == re else re
'''
# 不是sliding 的解法
count_pre = count_cur = 0 # count previous ones and count current ones for each zeros # O(n), O(1)
# e.x. 1 1 0 0 1 1 1 0 1 1
re = 0
for n in nums:
if n == 1:
count_cur += 1
else:
re = max(re, count_cur + count_pre)
count_pre = count_cur
count_cur = 0
re = max(re, count_cur + count_pre)
return re - 1 if len(nums) == re else re
'''