Skip to content

[bhyun-kim, 김병현] Week 6 solutions #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions container-with-most-water/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
11. Container With Most Water
https://leetcode.com/problems/container-with-most-water

Solution: Two Pointers
- Use two pointers to traverse the list
- Calculate the area between the two pointers
- Update the maximum area
- Move the pointer with the shorter height
- Return the maximum area

Time complexity: O(n)
- The two pointers traverse the list only once
Space complexity: O(1)
- No extra space is used
"""

from typing import List


class Solution:
def maxArea(self, height: List[int]) -> int:
left, right = 0, len(height) - 1
max_area = 0

while left < right:
shorter_height = min(height[left], height[right])
distance = right - left
area = shorter_height * distance
max_area = max(area, max_area)

if height[left] <= height[right]:
left += 1
else:
right -= 1

return max_area
5 changes: 3 additions & 2 deletions counting-bits/bhyun-kim.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ def countBits(self, n: int) -> List[int]:

from typing import List


class Solution:
def countBits(self, n: int) -> List[int]:
output = [0] * (n+1)
output = [0] * (n + 1)

for i in range(1, n+1):
for i in range(1, n + 1):
output[i] = output[i >> 1] + (i & 1)

return output
44 changes: 44 additions & 0 deletions find-minimum-in-rotated-sorted-array/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
153. Find Minimum in Rotated Sorted Array
https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/

Solution: Binary Search
- Find the center of the array
- Divide the array into two parts
- Compare the left and right values of each part
- If these values are in increasing order, return the left value of the first part
- Otherwise, find the minimum value of the left and right values of each part
- If the minimum value is the left value of the first part, recursively call the function with the first part
- Otherwise, recursively call the function with the second part

Time complexity: O(log n)
Space complexity: O(n)

"""


from typing import List


class Solution:
def findMin(self, nums: List[int]) -> int:
if len(nums) == 1:
return nums[0]

center = len(nums) // 2
arr1, arr2 = nums[:center], nums[center:]

arr1_left, arr1_right = arr1[0], arr1[-1]
arr2_left, arr2_right = arr2[0], arr2[-1]

if arr1_left < arr1_right < arr2_left < arr2_right:
return arr1_left

min_val = min(arr1_left, arr1_right)
min_val = min(min_val, arr2_left)
min_val = min(min_val, arr2_right)

if min_val in [arr1_left, arr1_right]:
return self.findMin(arr1)
else:
return self.findMin(arr2)
6 changes: 2 additions & 4 deletions group-anagrams/bhyun-kim.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,16 @@

class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:

hash_table = dict()
output = []

for s in strs:
count_s = ''.join(sorted(s))
count_s = "".join(sorted(s))
if count_s in hash_table:
idx = hash_table[count_s]
output[idx].append(s)
else:
hash_table[count_s] = len(output)
output.append([s])

return output

return output
54 changes: 54 additions & 0 deletions longest-repeating-character-replacement/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
424. Longest Repeating Character Replacement
https://leetcode.com/problems/longest-repeating-character-replacement/

Solution: Sliding Window
- Use a dictionary to store the number of occurrences of each character
- Use two pointers to traverse the string
- Increment the right pointer until the substring contains no repeating characters
- Increment the left pointer until the substring contains repeating characters
To do this,
- Find the maximum frequency of the characters in the substring
- If the length of the substring minus the maximum frequency is greater than k, increment the left pointer
- Update the maximum length of the substring
- Return the maximum length of the substring

Time complexity: O(n)
- The time complexity is O(n) because the two pointers traverse the string only once

Space complexity: O(n)
- Store the number of occurrences of each character in a dictionary
"""


from collections import defaultdict


class Solution:
def characterReplacement(self, s: str, k: int) -> int:
char_freq = defaultdict(int)
left, right = 0, 0
max_seq = 1
max_freq = 0

while right < len(s):
r = s[right]
char_freq[r] += 1

max_freq = 0
for v in char_freq.values():
max_freq = max(v, max_freq)

while right - left + 1 - max_freq > k and left < right:
l = s[left]
char_freq[l] -= 1
left += 1

max_freq = 0
for v in char_freq.values():
max_freq = max(v, max_freq)
Comment on lines +47 to +49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 작업이 무슨 의미가 있을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배열에서 가장 많이 나타났던 수 max_freq 를 찾는 과정이에요. 문제에서 k 개수 만큼 변경을 허용하는 부분이 있는데, 윈도우의 길이에서 max_freq 를 빼면 변경해야하는 문자들의 수가 나오고, 이를 k와 비교하는 과정입니다.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗, 질문의 의도가 잘못 전달이 되었군요. 저는 이 작업이 무엇을 하느냐를 여쭤본 게 아니라 왜 필요한지에 대해서 물어본 것입니다. max_freq를 여기서 왜 구하시나요? 어디다가 쓰시나요? 코드에서 그 게 잘 파악이 안 되서 여쭤봤습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sliding Window를 전개할 때 왼쪽 포인터를 전진시키는 조건으로 활용했습니다.

예를 들어,
s = "AABABBA", k = 1의 문제에서
현재 윈도우가 "AABA"라면 전체에서 가장 많이 나타나는 A의 빈도수를 빼면 남는 character의 수가 1이 됩니다. 이 때 1은 변경이 허용되는 횟수와 동일하기 때문에 현재 윈도우가 유효한 윈도우임을 판단합니다.

혹시.. 제가 질문 의도를 잘 이해한걸까요? 아니라면 한 번 더 알려주시면 감사드리겠습니다. 🙇

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 코멘트를 남긴 부분은 line 42에 조건문이 아니라 line 47-49입니다.
역시서 max_freq를 구하셨는데, 이 걸 어디에 활용하고 계신지 보이지 않아서 의아했습니다.
이 세 줄의 코드를 삭제하시고 답안 코드를 리트코드에 제출해보시겠어요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 부분 삭제해서 제출했는데 Time Limit Exceeded가 뜹니다. left를 갱신한 이후에 max_freq를 변경해야 while 문에 대한 조건이 바뀌기 때문에 그런 것 같습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 날짜가 길어지는 것 같아서 일단 Resolve하고 Merge 하겠습니다. 혹시 더 이야기 나누실 부분 있으시면 알려주세요!


max_seq = max(right - left + 1, max_seq)
right += 1

return max_seq
39 changes: 39 additions & 0 deletions longest-substring-without-repeating-characters/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
3. Longest Substring Without Repeating Characters
https://leetcode.com/problems/longest-substring-without-repeating-characters/

Solution: Sliding Window
- Use a dictionary to store the number of occurrences of each character
- Use two pointers to traverse the string
- Increment the right pointer until the substring contains no repeating characters
- Increment the left pointer until the substring contains repeating characters
- Update the maximum length of the substring
- Return the maximum length of the substring

Time complexity: O(n)
- The time complexity is O(n) because the two pointers traverse the string only once
Space complexity: O(n)
- Store the number of occurrences of each character in a dictionary
"""

from collections import defaultdict


class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
char_count = defaultdict(int)
right, left = 0, 0
max_seq = 0
while right < len(s):
r = s[right]
char_count[r] += 1

while char_count[r] > 1:
l = s[left]
char_count[l] -= 1
left += 1

max_seq = max(max_seq, right - left + 1)
right += 1

return max_seq
54 changes: 54 additions & 0 deletions search-in-rotated-sorted-array/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
33. Search in Rotated Sorted Array
https://leetcode.com/problems/search-in-rotated-sorted-array

Solution: Binary Search
- Find the center of the array
- Divide the array into two parts
- Compare the left and right values of each part
- If the target value is in the range of the left and right values of the first part, recursively call the function with the first part
- If the target value is in the range of the left and right values of the second part, recursively call the function with the second part
- If the first part is rotated, recursively call the function with the first part
- Otherwise, recursively call the function with the second part
- If the output is not -1, add the length of the first part to the output

Time complexity: O(log n)
- The time complexity is the same as the time complexity of the binary search algorithm
Space complexity: O(n)
- Store the divided array in two variables
"""

from typing import List


class Solution:
def search(self, nums: List[int], target: int) -> int:
if len(nums) == 1:
if target == nums[0]:
return 0
else:
return -1

center = len(nums) // 2
arr1, arr2 = nums[:center], nums[center:]

arr1_left, arr1_right = arr1[0], arr1[-1]
arr2_left, arr2_right = arr2[0], arr2[-1]

if arr1_left <= target <= arr1_right:
output = self.search(arr1, target)

elif arr2_left <= target <= arr2_right:
output = self.search(arr2, target)

if output != -1:
output += len(arr1)

elif arr1_right < arr1_left:
output = self.search(arr1, target)
else:
output = self.search(arr2, target)

if output != -1:
output += len(arr1)
return output