Compare commits
No commits in common. "0e1f96d20b37aa55c5cc1636bd0cd3df4c7e05cb" and "b904a8bb915e24f6e3689798ba29be3cacb57ee8" have entirely different histories.
0e1f96d20b
...
b904a8bb91
@ -1,26 +0,0 @@
|
|||||||
You are given a string `s` and an integer `k`. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most `k` times.
|
|
||||||
|
|
||||||
Return _the length of the longest substring containing the same letter you can get after performing the above operations_.
|
|
||||||
|
|
||||||
**Example 1:**
|
|
||||||
|
|
||||||
Input: s = "ABAB", k = 2
|
|
||||||
Output: 4
|
|
||||||
Explanation: Replace the two 'A's with two 'B's or vice versa.
|
|
||||||
|
|
||||||
|
|
||||||
**Example 2:**
|
|
||||||
|
|
||||||
Input: s = "AABABBA", k = 1
|
|
||||||
Output: 4
|
|
||||||
Explanation: Replace the one 'A' in the middle with 'B' and form "AABBBBA".
|
|
||||||
The substring "BBBB" has the longest repeating letters, which is 4.
|
|
||||||
|
|
||||||
|
|
||||||
**Constraints:**
|
|
||||||
|
|
||||||
* `1 <= s.length <= 105`
|
|
||||||
* `s` consists of only uppercase English letters.
|
|
||||||
* `0 <= k <= s.length`
|
|
||||||
|
|
||||||
https://leetcode.com/problems/longest-repeating-character-replacement
|
|
@ -1,42 +0,0 @@
|
|||||||
# Time: O(N^2)
|
|
||||||
# Space: O(N)
|
|
||||||
|
|
||||||
from collections import Counter
|
|
||||||
|
|
||||||
class Solution:
|
|
||||||
def characterReplacement(self, s: str, k: int) -> int:
|
|
||||||
'''
|
|
||||||
Sliding window approach
|
|
||||||
'''
|
|
||||||
|
|
||||||
def window_size(l, r):
|
|
||||||
return r - l + 1
|
|
||||||
|
|
||||||
# Need to keep track of frequency of each character in the
|
|
||||||
# window
|
|
||||||
count = Counter()
|
|
||||||
l = r = 0
|
|
||||||
result = 0
|
|
||||||
|
|
||||||
while r < len(s):
|
|
||||||
# Increment the frequency of the `r`th char
|
|
||||||
count.update(s[r])
|
|
||||||
|
|
||||||
# We can perform upto K replacements. So we prefer least num
|
|
||||||
# of replacements (<= K). In the current window, we can perform
|
|
||||||
# least replacements for the most common character in the range.
|
|
||||||
#
|
|
||||||
# e.g. AAABB K=2, in range 0 to 4, most common char is A, count=3
|
|
||||||
# so it just needs 5 - 3 = 2 replacements which is <= K which is ok.
|
|
||||||
#
|
|
||||||
# But, if K = 1, then we need 5 - 2 = 2 replacements for the same range
|
|
||||||
# but 2 > K so this window is not valid. We need to move left pointer in
|
|
||||||
# this case and reduce its count.
|
|
||||||
if window_size(l, r) - count.most_common(1)[0][1] > k:
|
|
||||||
count.subtract(s[l])
|
|
||||||
l += 1
|
|
||||||
|
|
||||||
result = max(result, window_size(l, r))
|
|
||||||
r += 1
|
|
||||||
|
|
||||||
return result
|
|
@ -1,43 +0,0 @@
|
|||||||
# Time: O(N)
|
|
||||||
# Space: O(N)
|
|
||||||
|
|
||||||
from collections import Counter
|
|
||||||
|
|
||||||
class Solution:
|
|
||||||
def characterReplacement(self, s: str, k: int) -> int:
|
|
||||||
'''
|
|
||||||
Sliding window approach, optimized
|
|
||||||
'''
|
|
||||||
|
|
||||||
def window_size(l, r):
|
|
||||||
return r - l + 1
|
|
||||||
|
|
||||||
# Need to keep track of frequency of each character in the
|
|
||||||
# window
|
|
||||||
count = Counter()
|
|
||||||
|
|
||||||
# We can optimize the prev sliding window approach by just keeping
|
|
||||||
# track of maximum frequency/count of an element we've seen so far.
|
|
||||||
maxf = 0
|
|
||||||
|
|
||||||
l = r = 0
|
|
||||||
result = 0
|
|
||||||
|
|
||||||
while r < len(s):
|
|
||||||
# Increment the frequency of the `r`th char
|
|
||||||
count.update(s[r])
|
|
||||||
|
|
||||||
# If right's frequency is bigger, make it the new
|
|
||||||
# max frequency
|
|
||||||
maxf = max(maxf, count[s[r]])
|
|
||||||
|
|
||||||
# Refer to neetcode: https://www.youtube.com/watch?v=gqXU1UyA8pk
|
|
||||||
# TODO: Document this approach my own way
|
|
||||||
if window_size(l, r) - maxf > k:
|
|
||||||
count.subtract(s[l])
|
|
||||||
l += 1
|
|
||||||
|
|
||||||
result = max(result, window_size(l, r))
|
|
||||||
r += 1
|
|
||||||
|
|
||||||
return result
|
|
@ -1,23 +0,0 @@
|
|||||||
Given two strings `s1` and `s2`, return `true` _if_ `s2` _contains a permutation of_ `s1`_, or_ `false` _otherwise_.
|
|
||||||
|
|
||||||
In other words, return `true` if one of `s1`'s permutations is the substring of `s2`.
|
|
||||||
|
|
||||||
**Example 1:**
|
|
||||||
|
|
||||||
Input: s1 = "ab", s2 = "eidbaooo"
|
|
||||||
Output: true
|
|
||||||
Explanation: s2 contains one permutation of s1 ("ba").
|
|
||||||
|
|
||||||
|
|
||||||
**Example 2:**
|
|
||||||
|
|
||||||
Input: s1 = "ab", s2 = "eidboaoo"
|
|
||||||
Output: false
|
|
||||||
|
|
||||||
|
|
||||||
**Constraints:**
|
|
||||||
|
|
||||||
* `1 <= s1.length, s2.length <= 104`
|
|
||||||
* `s1` and `s2` consist of lowercase English letters.
|
|
||||||
|
|
||||||
https://leetcode.com/problems/permutation-in-string
|
|
@ -1,31 +0,0 @@
|
|||||||
# Time: O(S1 · S2) ; S2 is len(s1) and S2 is len(S2)
|
|
||||||
# Space: O(S2 · 26)
|
|
||||||
|
|
||||||
from collections import Counter
|
|
||||||
|
|
||||||
class Solution:
|
|
||||||
def checkInclusion(self, s1: str, s2: str) -> bool:
|
|
||||||
if len(s1) > len(s2): return False
|
|
||||||
|
|
||||||
if len(s1) == len(s2):
|
|
||||||
return Counter(s1) == Counter(s2)
|
|
||||||
|
|
||||||
s1_counter = Counter(s1)
|
|
||||||
|
|
||||||
target_length = len(s1)
|
|
||||||
end = target_length - 1
|
|
||||||
|
|
||||||
while end < len(s2):
|
|
||||||
start = end - target_length + 1
|
|
||||||
curr_substring = s2[start:end + 1]
|
|
||||||
|
|
||||||
# Check if counters match for the given substring
|
|
||||||
# indicated by start:end with a length of target_length
|
|
||||||
if s1_counter == Counter(curr_substring):
|
|
||||||
return True
|
|
||||||
|
|
||||||
end += 1
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
|||||||
class Solution:
|
|
||||||
def checkInclusion(self, s1: str, s2: str) -> bool:
|
|
||||||
'''
|
|
||||||
Sliding window, better space utilization
|
|
||||||
'''
|
|
||||||
|
|
||||||
if len(s1) > len(s2): return False
|
|
||||||
|
|
||||||
def get_letter_index(letter):
|
|
||||||
'''
|
|
||||||
Problem only concerns with lowercase letters
|
|
||||||
'''
|
|
||||||
return ord(letter) - ord('a')
|
|
||||||
|
|
||||||
|
|
||||||
s1_count, s2_count = [0] * 26, [0] * 26
|
|
||||||
for i in range(len(s1)):
|
|
||||||
s1_count[get_letter_index(s1[i])] += 1
|
|
||||||
s2_count[get_letter_index(s2[i])] += 1
|
|
||||||
|
|
||||||
# Keep a `count_matches` variable that tells us how many
|
|
||||||
# counts of a-z from s1 match a-z in the window of s2
|
|
||||||
count_matches = 0
|
|
||||||
|
|
||||||
for i in range(26):
|
|
||||||
if s1_count[i] == s2_count[i]:
|
|
||||||
count_matches += 1
|
|
||||||
|
|
||||||
# It's possible that we get a perfect match right after the
|
|
||||||
# above initial computation. If yes, yay!
|
|
||||||
if count_matches == 26:
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
# Start from the very next character after figuring out the
|
|
||||||
# initial `count_matches` value which would be at len(s1)
|
|
||||||
l = 0
|
|
||||||
for r in range(len(s1), len(s2)):
|
|
||||||
#
|
|
||||||
# Adding rightmost letter
|
|
||||||
#
|
|
||||||
li = get_letter_index(s2[r])
|
|
||||||
s2_count[li] += 1
|
|
||||||
|
|
||||||
if s1_count[li] == s2_count[li]:
|
|
||||||
count_matches += 1
|
|
||||||
# If after adding new right letter, count increased by 1 for
|
|
||||||
# the letter index, then that means total matches also reduced
|
|
||||||
# by 1
|
|
||||||
elif s1_count[li] + 1 == s2_count[li]:
|
|
||||||
count_matches -= 1
|
|
||||||
|
|
||||||
#
|
|
||||||
# Removing leftmost letter
|
|
||||||
#
|
|
||||||
li = get_letter_index(s2[l])
|
|
||||||
s2_count[li] -= 1
|
|
||||||
|
|
||||||
if s1_count[li] == s2_count[li]:
|
|
||||||
count_matches += 1
|
|
||||||
# If after removing leftmost letter, count decreased by 1, then
|
|
||||||
# our total matches also reduced by 1
|
|
||||||
elif s1_count[li] - 1 == s2_count[li]:
|
|
||||||
count_matches -= 1
|
|
||||||
|
|
||||||
if count_matches == 26: return True
|
|
||||||
|
|
||||||
l += 1
|
|
||||||
|
|
||||||
return count_matches == 26
|
|
Loading…
Reference in New Issue
Block a user