Skip to content
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
54 changes: 54 additions & 0 deletions 3sum/gcount85.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
# Intuition
처음에는 1주차의 Two Sum 문제 풀이를 응용하여, 배열 순회 + 해시 테이블 만들어 값 찾기를 시도했으나
정렬 + 투포인터 풀이가 더 빠르므로 그렇게 제출했습니다.

# Approach
nums 배열을 순회하면서 -nums[i]를 합으로 하는 두 수를 나머지 배열 부분에서 찾는다.
찾을 때는 정렬 & 투포인터를 활용하여 중복을 건너 뛰는 방식으로 속도를 높인다.


# Complexity
- Time complexity: 정렬 + 투포인터 이중 반복으로 O(N^2)

- Space complexity: 정렬 하는데에 O(N) , answer 배열 생성하는데에 O(M)
"""


class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
nums.sort() # O(NlogN)
n = len(nums)
answer = []

for i in range(n - 2): # 이중 반복문 O(N^2)
# 중복 제거
if i > 0 and nums[i] == nums[i - 1]:
continue

# nums[i]가 0보다 크면 뒤도 다 양수라 종료 가능
if nums[i] > 0:
break

left, right = i + 1, n - 1

while left < right:
total = nums[i] + nums[left] + nums[right]

if total == 0:
answer.append([nums[i], nums[left], nums[right]])
left += 1
right -= 1

# left/right 중복 제거
while left < right and nums[left] == nums[left - 1]:
left += 1
while left < right and nums[right] == nums[right + 1]:
right -= 1

elif total < 0:
left += 1
else:
right -= 1

return answer
26 changes: 26 additions & 0 deletions climbing-stairs/gcount85.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""
# Intuition
마지막 계단에 도착하는 경우의 수는, 2스텝 전의 경우의 수와 1스텝 전의 경우의 수를 합한 값입니다.

# Approach
dp[n] = dp[n-1] + dp[n-2]

# Complexity
- Time complexity: O(n)

- Space complexity: O(1)
"""


class Solution:
def climbStairs(self, n: int) -> int:
b = 1 # n이 1일때
if n == 1:
return b
a = 2 # n이 2일때
if n == 2:
return a

for n in range(3, n + 1): # O(n)
a, b = a + b, a
return a
38 changes: 38 additions & 0 deletions product-of-array-except-self/gcount85.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
# Approach
모든 원소끼리 곱한 다음에 nums 배열을 순회하며 그 값을 해당 원소로 나눈다.
이때 0의 개수와 0을 제외한 곱의 값도 같이 구한다.
0이 2개 이상이면 정답은 모두 0이며,
0이 1개면 0을 제외한 곱의 값을 사용한다.

# Complexity
- Time complexity: O(n)

- Space complexity: O(n)
"""


# Code
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
product = 1
non_zero_product = 1
zero_count = 0
for num in nums: # O(n) Time complexity
if num == 0:
zero_count += 1
non_zero_product *= 1
else:
non_zero_product *= num
product *= num

if zero_count > 1:
return [0] * len(nums) # O(n) space complexity

answer = [] # O(n) space complexity
for i in range(len(nums)): # O(n) Time complexity
if nums[i] == 0:
answer.append(non_zero_product)
else:
answer.append(int(product / nums[i]))
return answer
33 changes: 33 additions & 0 deletions valid-anagram/gcount85.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
# Approach
문자열 s를 구성하는 문자의 개수를 세는 딕셔너리 word_dict를 만들고,
문자열 t를 순회하며 word_dict에 키가 있는지 확인합니다.
키가 없으면: 에너그램 불가능.
키가 있으면: 값에서 -1하고, 음수인지 확인하여 에너그램 여부를 판별합니다.

# Complexity
- Time complexity: s의 길이가 N이고, t의 길이가 M일 때 O(N+M)

- Space complexity: O(N+M)
"""

from collections import defaultdict


class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t):
return False

word_dict = defaultdict(int)
for ch in s: # O(N)
word_dict[ch] += 1

for ch in t: # O(M)
if ch not in word_dict:
return False
word_dict[ch] -= 1
if word_dict[ch] < 0:
return False

return True
31 changes: 31 additions & 0 deletions validate-binary-search-tree/gcount85.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
# https://leetcode.com/problems/validate-binary-search-tree/description/
# Intuition
BST를 중위 순회하면 오름차순으로 값이 정렬된다는 점에 착안했습니다.

# Complexity
- Time complexity: 노드의 개수를 N이라고 할 때, O(N)

- Space complexity: 재귀로 트리를 순회하면서 호출 스택이 쌓이는데
트리의 높이를 H라고 할 때, 호출 스택은 H 만큼 쌓입니다. => 공간 복잡도 O(H)
"""


class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
prev = [None]

def inorder(node):
if not node:
return True

if not inorder(node.left):
return False

if prev[0] is not None and prev[0] >= node.val:
return False
prev[0] = node.val

return inorder(node.right)

return inorder(root)
Loading