diff --git a/0424.Longest-Repeating-Character-Replacement/memo.md b/0424.Longest-Repeating-Character-Replacement/memo.md new file mode 100644 index 0000000..ccf8cee --- /dev/null +++ b/0424.Longest-Repeating-Character-Replacement/memo.md @@ -0,0 +1,31 @@ +# 424. Longest Repeating Character Replacement + +## step1 +sliding windowを使う。 +23mほどかかった。 + +時間計算量はO(N)。ただし文字列に含まれるユニークな文字を定数とみなした場合。 + +他の解法は思いつかない。Hashmapがヒントにあるがこれをどう使うのかわからない。 + +## 他の人のコード + +https://github.com/olsen-blue/Arai60/pull/49#issuecomment-3649179920 + +https://github.com/Exzrgs/LeetCode/pull/48 + +hashmapの使い方はこうするのか + +https://github.com/potrue/leetcode/pull/65/changes + +maxを取り出す部分でheapを使った解法。 + +heapの遅延評価: heapからの削除が難しいからとりあえずcounterだけ更新しておいて、heapから取り出したときの値は一致していなかったら捨てる + +実際にはheapの定数倍の計算量で遅くなるようだ。 + +https://leetcode.com/problems/longest-repeating-character-replacement/solutions/8301734/optimal-solution-by-nthapa000-lejz/ + +max_frequencyは更新されるときだけ計算しても良く、時間計算量が小さくなる。が、毎回計算した方がわかりやすいようにも思う。 + +## step2 diff --git a/0424.Longest-Repeating-Character-Replacement/step1.py b/0424.Longest-Repeating-Character-Replacement/step1.py new file mode 100644 index 0000000..becffe7 --- /dev/null +++ b/0424.Longest-Repeating-Character-Replacement/step1.py @@ -0,0 +1,21 @@ +class Solution: + def characterReplacement(self, s: str, k: int) -> int: + length_of_longest = 0 + + def update_longest(target_alphabet): + nonlocal length_of_longest + left = 0 + num_other_than_target = 0 + for right in range(len(s)): + if s[right] != target_alphabet: + num_other_than_target += 1 + while num_other_than_target > k: + if s[left] != target_alphabet: + num_other_than_target -= 1 + left += 1 + length_of_longest = max(length_of_longest, right - left + 1) + + for target_alphabet in set(s): + update_longest(target_alphabet) + + return length_of_longest diff --git a/0424.Longest-Repeating-Character-Replacement/step2.py b/0424.Longest-Repeating-Character-Replacement/step2.py new file mode 100644 index 0000000..81204b5 --- /dev/null +++ b/0424.Longest-Repeating-Character-Replacement/step2.py @@ -0,0 +1,19 @@ +import collections + + +class Solution: + def characterReplacement(self, s: str, k: int) -> int: + count = collections.defaultdict(int) + left = 0 + length_of_longest = 0 + + for right in range(len(s)): + count[s[right]] += 1 + + while (right - left + 1) - max(count.values()) > k: + count[s[left]] -= 1 + left += 1 + + length_of_longest = max(length_of_longest, right - left + 1) + + return length_of_longest diff --git a/0424.Longest-Repeating-Character-Replacement/step2_heap.py b/0424.Longest-Repeating-Character-Replacement/step2_heap.py new file mode 100644 index 0000000..682b07b --- /dev/null +++ b/0424.Longest-Repeating-Character-Replacement/step2_heap.py @@ -0,0 +1,28 @@ +import collections +import heapq + + +class Solution: + def characterReplacement(self, s: str, k: int) -> int: + count = collections.defaultdict(int) + left = 0 + length_of_longest = 0 + heap = [] + + def get_max_count(): + while -heap[0][0] != count[heap[0][1]]: + heapq.heappop(heap) + return -heap[0][0] + + for right in range(len(s)): + count[s[right]] += 1 + heapq.heappush(heap, (-count[s[right]], s[right])) + + while (right - left + 1) - get_max_count() > k: + count[s[left]] -= 1 + heapq.heappush(heap, (-count[s[left]], s[left])) + left += 1 + + length_of_longest = max(length_of_longest, right - left + 1) + + return length_of_longest diff --git a/0424.Longest-Repeating-Character-Replacement/step2_heap_revised.py b/0424.Longest-Repeating-Character-Replacement/step2_heap_revised.py new file mode 100644 index 0000000..2408490 --- /dev/null +++ b/0424.Longest-Repeating-Character-Replacement/step2_heap_revised.py @@ -0,0 +1,28 @@ +import collections +import heapq + + +class Solution: + def characterReplacement(self, s: str, k: int) -> int: + count = collections.defaultdict(int) + left = 0 + length_of_longest = 0 + heap = [] # contains (count, alphabet) in max heap + + def get_max_count(): + while heap[0][0] != count[heap[0][1]]: + heapq.heappop_max(heap) + return heap[0][0] + + for right in range(len(s)): + count[s[right]] += 1 + heapq.heappush_max(heap, (count[s[right]], s[right])) + + while (right - left + 1) - get_max_count() > k: + count[s[left]] -= 1 + heapq.heappush_max(heap, (count[s[left]], s[left])) + left += 1 + + length_of_longest = max(length_of_longest, right - left + 1) + + return length_of_longest diff --git a/0424.Longest-Repeating-Character-Replacement/step2_max_frequency.py b/0424.Longest-Repeating-Character-Replacement/step2_max_frequency.py new file mode 100644 index 0000000..f90f040 --- /dev/null +++ b/0424.Longest-Repeating-Character-Replacement/step2_max_frequency.py @@ -0,0 +1,21 @@ +import collections + + +class Solution: + def characterReplacement(self, s: str, k: int) -> int: + count = collections.defaultdict(int) + max_frequency = 0 + left = 0 + length_of_longest = 0 + + for right in range(len(s)): + count[s[right]] += 1 + max_frequency = max(max_frequency, count[s[right]]) + + while (right - left + 1) - max_frequency > k: + count[s[left]] -= 1 + left += 1 + + length_of_longest = max(length_of_longest, right - left + 1) + + return length_of_longest