Skip to content

Commit 6868da5

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 6ced330 + 0ef1547 commit 6868da5

File tree

18 files changed

+759
-38
lines changed

18 files changed

+759
-38
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from typing import List
2+
from unittest import TestCase, main
3+
4+
5+
class Solution:
6+
def findMin(self, nums: List[int]) -> int:
7+
return self.solve_binary_search(nums)
8+
9+
"""
10+
Runtime: 32 ms (Beats 97.56%)
11+
Time Complexity: O(log n)
12+
- 크기가 n인 배열에 대한 이분탐색에 O(log n)
13+
- while 조건문 판단에 O(2), and 연산이므로 단축 평가에 의해 upper bound
14+
- 엣지 케이스 처리를 위한 마지막 lo, hi 2개 항에 대한 min연산에 O(2)
15+
> O(log n) * O(2) + O(2) ~= O(log n)
16+
17+
Memory: 16.82 (Beats 50.00%)
18+
Space Complexity: O(1)
19+
> 이분탐색에 필요한 정수형 변수 lo, hi, mid 3개만 사용했으므로 n과 상관없이 O(1)
20+
"""
21+
def solve_binary_search(self, nums: List[int]) -> int:
22+
lo, hi = 0, len(nums) - 1
23+
while lo < hi and nums[hi] < nums[lo]:
24+
mid = (lo + hi) // 2
25+
if nums[lo] < nums[mid]:
26+
lo = mid
27+
elif nums[mid] < nums[hi]:
28+
hi = mid
29+
else:
30+
break
31+
32+
return min(nums[lo], nums[hi])
33+
34+
35+
class _LeetCodeTestCases(TestCase):
36+
def test_1(self):
37+
nums = [2, 1]
38+
output = 1
39+
self.assertEqual(Solution().findMin(nums), output)
40+
41+
42+
if __name__ == '__main__':
43+
main()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution:
2+
# 시간복잡도: O(logN)
3+
# 공간복잡도: O(1)
4+
def findMin(self, nums: List[int]) -> int:
5+
n = len(nums)
6+
st, en = 0, n-1
7+
while st < en:
8+
mid = (st+en)//2
9+
if nums[mid] > nums[en]:
10+
st = mid + 1
11+
else:
12+
en = mid
13+
14+
return nums[st]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from typing import List
2+
3+
4+
class Solution:
5+
def findMin(self, nums: List[int]) -> int:
6+
"""
7+
- Idea: 회전된 정렬 배열에서 가장 작은 값을 찾기 위해 두 개의 포인터, left, right를 이용한다.
8+
두 개의 포인터는 조건에 따라 배열에서 탐색할 범위를 줄여가는데 활용된다.
9+
- Time Complexity: O(logn). n은 배열의 크기이다.
10+
매번 배열을 절반으로 나눠서 탐색 범위를 줄이기 때문에 O(logn) 시간이 걸린다.
11+
- Space Complexity: O(1). 배열의 크기와 상관없이 left, right, mid 변수만 사용되므로
12+
상수 공간만 차지한다.
13+
"""
14+
left, right = 0, len(nums) - 1
15+
16+
while left < right:
17+
mid = (left + right) // 2
18+
19+
if nums[right] < nums[mid]:
20+
left = mid + 1
21+
else:
22+
right = mid
23+
24+
return nums[left]
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @description
3+
* brainstorming:
4+
* brute force
5+
*
6+
* n = length of head
7+
* time complexity: O(n)
8+
* space complexity: O(1)
9+
*/
10+
var findMin = function (nums) {
11+
let answer = 5000;
12+
nums.forEach((num) => (answer = Math.min(answer, num)));
13+
14+
return answer;
15+
};
16+
17+
/* n = length of head
18+
* time complexity: O(n)
19+
* space complexity: O(1)
20+
*/
21+
var findMin = function (nums) {
22+
let answer = nums[0];
23+
if (nums.length === 1) return answer;
24+
if (answer < nums[nums.length - 1]) return answer;
25+
26+
for (let i = nums.length - 1; i >= 0; i--) {
27+
if (answer < nums[i]) return answer;
28+
answer = nums[i];
29+
}
30+
31+
return answer;
32+
};

linked-list-cycle/EGON.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from typing import Optional
2+
from unittest import TestCase, main
3+
4+
5+
# Definition for singly-linked list.
6+
class ListNode:
7+
def __init__(self, x):
8+
self.val = x
9+
self.next = None
10+
11+
12+
class Solution:
13+
def hasCycle(self, head: Optional[ListNode]) -> bool:
14+
return self.solve(head)
15+
16+
"""
17+
Runtime: 37 ms (Beats 93.02%)
18+
Time Complexity: O(n)
19+
> head부터 next가 있는 동안 선형적으로 조회하므로 O(n)
20+
21+
Memory: 18.62 (Beats 98.22%)
22+
Space Complexity: O(1)
23+
> head를 제외하고 아무 변수도 사용하지 않았으므로 O(1)
24+
"""
25+
def solve(self, head: Optional[ListNode]) -> bool:
26+
if not head:
27+
return False
28+
29+
while head.next:
30+
if head.next and head.next.val is None:
31+
return True
32+
33+
head.val = None
34+
head = head.next
35+
36+
return False
37+
38+
39+
class _LeetCodeTestCases(TestCase):
40+
def test_1(self):
41+
head = None
42+
output = False
43+
self.assertEqual(Solution().hasCycle(head), output)
44+
45+
46+
if __name__ == '__main__':
47+
main()

linked-list-cycle/kayden.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution:
2+
# 시간복잡도: O(N)
3+
# 공간복잡도: O(N)
4+
def hasCycle(self, head: Optional[ListNode]) -> bool:
5+
6+
visited = set()
7+
while head:
8+
if head in visited:
9+
return True
10+
11+
visited.add(head)
12+
head = head.next
13+
14+
return False

linked-list-cycle/mangodm-web.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from typing import Optional
2+
3+
4+
# Definition for singly-linked list.
5+
class ListNode:
6+
def __init__(self, x: int) -> None:
7+
self.val = x
8+
self.next = None
9+
10+
11+
class Solution:
12+
def hasCycle(self, head: Optional[ListNode]) -> bool:
13+
"""
14+
- Idea: 사이클이 있는 연결 리스트인지 판단하기 위해 두 개의 포인터, slow와 fast를 사용한다.
15+
slow 포인터는 한번에 한 칸씩, fast 포인터는 한번에 두 칸씩 이동한다.
16+
만약 두 포인터가 만나면, 리스트에 사이클이 존재한다고 판단할 수 있다.
17+
fast가 리스트의 끝에 도달한다면 사이클이 없다고 판단한다.
18+
- Time Complexity: O(n). n은 리스트에 포함된 노드의 개수다.
19+
사이클이 없는 경우, fast 포인터는 리스트 끝까지 이동한다.
20+
사이클이 있는 경우, 두 포인터가 만날 때까지 이동하므로 O(n)의 시간이 소요된다.
21+
- Space Complexity: O(1). 연결 리스트의 크기와 상관없이 slow와 fast 변수만 사용되므로
22+
상수 공간만 차지한다.
23+
"""
24+
slow, fast = head, head
25+
26+
while fast and fast.next:
27+
slow = slow.next
28+
fast = fast.next.next
29+
30+
if slow == fast:
31+
return True
32+
33+
return False

linked-list-cycle/sunjae95.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @description
3+
* brainstorming:
4+
* hash table
5+
*
6+
* n = length of head
7+
* time complexity: O(n)
8+
* space complexity: O(n)
9+
*/
10+
var hasCycle = function (head) {
11+
const set = new Set();
12+
let node = head;
13+
14+
while (node) {
15+
if (set.has(node)) return true;
16+
set.add(node);
17+
node = node.next;
18+
}
19+
20+
return false;
21+
};

maximum-product-subarray/EGON.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from typing import List
2+
from unittest import TestCase, main
3+
4+
5+
class Solution:
6+
def maxProduct(self, nums: List[int]) -> int:
7+
return self.solveWithDP(nums)
8+
9+
"""
10+
Runtime: 71 ms (Beats 61.13%)
11+
Time Complexity: O(n)
12+
- dp 배열 초기화를 위한 nums.copy()에 O(n)
13+
- range(1, L) 조회하며 조건에 따라 연산에 O(n - 1)
14+
- range(L) 조회하며 max 계산에 O(n)
15+
> O(n) + O(n - 1) + O(n) ~= O(n)
16+
17+
Memory: 17.75 MB (Beats 11.09%)
18+
Space Complexity: O(n)
19+
- 크기가 n인 배열 2개 사용했으므로 2 * O(n)
20+
> O(2n) ~= O(n)
21+
"""
22+
def solveWithDP(self, nums: List[int]) -> int:
23+
L = len(nums)
24+
forward_product, backward_product = nums.copy(), nums.copy()
25+
for i in range(1, L):
26+
if forward_product[i - 1] != 0:
27+
forward_product[i] *= forward_product[i - 1]
28+
29+
if backward_product[L - i] != 0:
30+
backward_product[L - i - 1] *= backward_product[L - i]
31+
32+
result = nums[0]
33+
for i in range(L):
34+
result = max(result, forward_product[i], backward_product[i])
35+
36+
return result
37+
38+
39+
class _LeetCodeTestCases(TestCase):
40+
def test_1(self):
41+
nums = [2,3,-2,4]
42+
output = 6
43+
self.assertEqual(Solution.maxProduct(Solution(), nums), output)
44+
45+
def test_2(self):
46+
nums = [-2,0,-1]
47+
output = 0
48+
self.assertEqual(Solution.maxProduct(Solution(), nums), output)
49+
50+
def test_3(self):
51+
nums = [-2]
52+
output = -2
53+
self.assertEqual(Solution.maxProduct(Solution(), nums), output)
54+
55+
def test_4(self):
56+
nums = [0,-3,-2,-3,-2,2,-3,0,1,-1]
57+
output = 72
58+
self.assertEqual(Solution.maxProduct(Solution(), nums), output)
59+
60+
def test_5(self):
61+
nums = [7, -2, -4]
62+
output = 56
63+
self.assertEqual(Solution.maxProduct(Solution(), nums), output)
64+
65+
66+
if __name__ == '__main__':
67+
main()

0 commit comments

Comments
 (0)