-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #525 from lymchgmk/feat/week9
[EGON]] Week9 Solutions
- Loading branch information
Showing
6 changed files
with
372 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from typing import List | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def findMin(self, nums: List[int]) -> int: | ||
return self.solve_binary_search(nums) | ||
|
||
""" | ||
Runtime: 32 ms (Beats 97.56%) | ||
Time Complexity: O(log n) | ||
- 크기가 n인 배열에 대한 이분탐색에 O(log n) | ||
- while 조건문 판단에 O(2), and 연산이므로 단축 평가에 의해 upper bound | ||
- 엣지 케이스 처리를 위한 마지막 lo, hi 2개 항에 대한 min연산에 O(2) | ||
> O(log n) * O(2) + O(2) ~= O(log n) | ||
Memory: 16.82 (Beats 50.00%) | ||
Space Complexity: O(1) | ||
> 이분탐색에 필요한 정수형 변수 lo, hi, mid 3개만 사용했으므로 n과 상관없이 O(1) | ||
""" | ||
def solve_binary_search(self, nums: List[int]) -> int: | ||
lo, hi = 0, len(nums) - 1 | ||
while lo < hi and nums[hi] < nums[lo]: | ||
mid = (lo + hi) // 2 | ||
if nums[lo] < nums[mid]: | ||
lo = mid | ||
elif nums[mid] < nums[hi]: | ||
hi = mid | ||
else: | ||
break | ||
|
||
return min(nums[lo], nums[hi]) | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
nums = [2, 1] | ||
output = 1 | ||
self.assertEqual(Solution().findMin(nums), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from typing import Optional | ||
from unittest import TestCase, main | ||
|
||
|
||
# Definition for singly-linked list. | ||
class ListNode: | ||
def __init__(self, x): | ||
self.val = x | ||
self.next = None | ||
|
||
|
||
class Solution: | ||
def hasCycle(self, head: Optional[ListNode]) -> bool: | ||
return self.solve(head) | ||
|
||
""" | ||
Runtime: 37 ms (Beats 93.02%) | ||
Time Complexity: O(n) | ||
> head부터 next가 있는 동안 선형적으로 조회하므로 O(n) | ||
Memory: 18.62 (Beats 98.22%) | ||
Space Complexity: O(1) | ||
> head를 제외하고 아무 변수도 사용하지 않았으므로 O(1) | ||
""" | ||
def solve(self, head: Optional[ListNode]) -> bool: | ||
if not head: | ||
return False | ||
|
||
while head.next: | ||
if head.next and head.next.val is None: | ||
return True | ||
|
||
head.val = None | ||
head = head.next | ||
|
||
return False | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
head = None | ||
output = False | ||
self.assertEqual(Solution().hasCycle(head), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from typing import List | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def maxProduct(self, nums: List[int]) -> int: | ||
return self.solveWithDP(nums) | ||
|
||
""" | ||
Runtime: 71 ms (Beats 61.13%) | ||
Time Complexity: O(n) | ||
- dp 배열 초기화를 위한 nums.copy()에 O(n) | ||
- range(1, L) 조회하며 조건에 따라 연산에 O(n - 1) | ||
- range(L) 조회하며 max 계산에 O(n) | ||
> O(n) + O(n - 1) + O(n) ~= O(n) | ||
Memory: 17.75 MB (Beats 11.09%) | ||
Space Complexity: O(n) | ||
- 크기가 n인 배열 2개 사용했으므로 2 * O(n) | ||
> O(2n) ~= O(n) | ||
""" | ||
def solveWithDP(self, nums: List[int]) -> int: | ||
L = len(nums) | ||
forward_product, backward_product = nums.copy(), nums.copy() | ||
for i in range(1, L): | ||
if forward_product[i - 1] != 0: | ||
forward_product[i] *= forward_product[i - 1] | ||
|
||
if backward_product[L - i] != 0: | ||
backward_product[L - i - 1] *= backward_product[L - i] | ||
|
||
result = nums[0] | ||
for i in range(L): | ||
result = max(result, forward_product[i], backward_product[i]) | ||
|
||
return result | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
nums = [2,3,-2,4] | ||
output = 6 | ||
self.assertEqual(Solution.maxProduct(Solution(), nums), output) | ||
|
||
def test_2(self): | ||
nums = [-2,0,-1] | ||
output = 0 | ||
self.assertEqual(Solution.maxProduct(Solution(), nums), output) | ||
|
||
def test_3(self): | ||
nums = [-2] | ||
output = -2 | ||
self.assertEqual(Solution.maxProduct(Solution(), nums), output) | ||
|
||
def test_4(self): | ||
nums = [0,-3,-2,-3,-2,2,-3,0,1,-1] | ||
output = 72 | ||
self.assertEqual(Solution.maxProduct(Solution(), nums), output) | ||
|
||
def test_5(self): | ||
nums = [7, -2, -4] | ||
output = 56 | ||
self.assertEqual(Solution.maxProduct(Solution(), nums), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from collections import Counter | ||
from typing import List | ||
from unittest import TestCase, main | ||
|
||
|
||
class Solution: | ||
def minWindow(self, s: str, t: str) -> str: | ||
return self.solve_two_pointer(s, t) | ||
|
||
""" | ||
Runtime: 129 ms (Beats 50.44%) | ||
Time Complexity: O(S) | ||
- 문자열 s를 enumerate로 순회하는데 O(S) | ||
- 순회 후 left를 갱신하는 while문에서 left가 0부터 n까지 단조증가하므로 총 조회는 O(S) | ||
> O(S) + O(S) ~= O(S) | ||
Memory: 17.32 MB (Beats 32.52%) | ||
Space Complexity: O(S) | ||
- counter 변수의 초기 크기는 O(T) | ||
- 반복문을 조회하며 counter 갱신, 최악의 경우 s의 모든 문자가 다르고 s == t인 경우 이므로 O(S), upper bound | ||
> O(S) | ||
""" | ||
def solve_two_pointer(self, s: str, t: str) -> str: | ||
counter = Counter(t) | ||
missing = len(t) | ||
left = start = end = 0 | ||
for right, char in enumerate(s, start=1): | ||
missing -= counter[char] > 0 | ||
counter[char] -= 1 | ||
|
||
if missing == 0: | ||
while left < right and counter[s[left]] < 0: | ||
counter[s[left]] += 1 | ||
left += 1 | ||
|
||
if not end or right - left <= end - start: | ||
start, end = left, right | ||
|
||
counter[s[left]] += 1 | ||
missing += 1 | ||
left += 1 | ||
|
||
return s[start:end] | ||
|
||
|
||
class _LeetCodeTestCases(TestCase): | ||
def test_1(self): | ||
s = "ADOBECODEBANC" | ||
t = "ABC" | ||
output = "BANC" | ||
self.assertEqual(Solution.minWindow(Solution(), s, t), output) | ||
|
||
def test_2(self): | ||
s = "a" | ||
t = "a" | ||
output = "a" | ||
self.assertEqual(Solution.minWindow(Solution(), s, t), output) | ||
|
||
def test_3(self): | ||
s = "a" | ||
t = "aa" | ||
output = "" | ||
self.assertEqual(Solution.minWindow(Solution(), s, t), output) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.