Skip to content
Closed
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
12 changes: 6 additions & 6 deletions 3sum/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Sorting
  • 설명: 3sum 문제에서 정렬 후 두 포인터(left, right)를 이용해 합이 0이 되는 조합을 찾는 패턴을 사용합니다. 중복 제거를 위한 스킵도 포함되어 있어 대표적인 Two Pointers 흐름입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n^2)
Space O(1)

피드백: 정렬 후 중복 제거를 위해 i 루프에서 건너뛰기와 left/right 중복 검사로 중복 결과를 제거한다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
answer = []
nums.sort()
nums.sort()

for i in range(len(nums)):
# 중복된 원소가 있는 경우 똑같이 검사할 필요가 없으므로 건너뛴다.
if i > 0 and nums[i] == nums[i-1]:
continue
continue

left, right = i+1, len(nums) - 1

while left < right:
while left < right:
total = nums[i] + nums[left] + nums[right]
if total == 0:
answer.append([nums[i], nums[left], nums[right]])
# left, right 포인터를 둘다 한칸씩 이동시켜 다음 조합을 검사한다.
left += 1
right -= 1

# 중복된 원소가 있는 경우 같은 정답 조합을 방지한다
# 중복된 원소가 있는 경우 같은 정답 조합을 방지한다
while left < right and nums[left] == nums[left -1]:
left += 1

elif total < 0:
left += 1
else:
else:
right -= 1
return answer
4 changes: 2 additions & 2 deletions climbing-stairs/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Dynamic Programming
  • 설명: 점화식 ways(n) = ways(n-1) + ways(n-2) 를 이용한 피보나치형 DP로 n번째 계단 수를 구하는 전형적인 다이나믹 프로그래밍 풀이입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 초기 조건 처리와 점화식을 이용해 반복으로 계산한다.

개선 제안: 메모리 사용을 줄이려면 공간을 O(1)으로 최적화 가능하다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class Solution:
def climbStairs(self, n: int) -> int:
answer = 0
answer = 0
if n == 1: # ways(1) = 1
return 1

if n == 2: # ways(2) = 2
return 2

dp = [0] * 46 # 1 <= n <= 45
dp[1] = 1
dp[2] = 2
Expand Down
23 changes: 23 additions & 0 deletions combination-sum/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Backtracking
  • 설명: Combination Sum 문제를 재귀적으로 탐색하며 모든 경우를 시도하는 백트래킹 패턴으로 구현되어 있습니다. 가지치기 조건으로 합이 목표를 넘으면 가지치고, 경로를 복사해 저장합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(k * number_of_combinations)
Space O(k)

피드백: path를 깊은 복사해 저장하고 재귀적으로 백트래킹한다.

개선 제안: 중복 조합 제거를 위한 정렬 및 시작 인덱스 관리가 필요하다면 초기 후보를 정렬하는 것도 고려.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
answer = []

def backtracking(start_idx, total, path):
if target == total:
answer.append(path[:]) # 새로운 리스트 객체를 만들어서 저장함.
# 리스트가 mutable 객체이므로 path[:] 로 복사하지 않으면 path 가 바뀔 때 answer 안의 값도 바뀌게 된다.
return

if target < total:
return

for idx in range(start_idx, len(candidates)):
new_node = candidates[idx] # 동일한 숫자 재사용 가능함. start_idx 도 포함한다.
path.append(new_node)

backtracking(idx, total + new_node, path)
# 선택 취소
path.pop()

backtracking(0, 0, [])
return answer
2 changes: 1 addition & 1 deletion contains-duplicate/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Hash Map / Hash Set
  • 설명: 배열 원소 중복 여부를 확인하기 위해 집합(Hash Set)으로 중복 여부를 검사하는 패턴입니다. 한 번의 스캔으로 고유 원소 수를 비교하여 중복 여부를 판단합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 리스트 길이와 집합 길이를 비교해 중복 여부를 판단한다.

개선 제안: 추가 최적화가 필요하면 해시 세트를 활용하는 방법은 충분히 효율적이다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
first = len(nums) # O(1) : 리스트 객체는 이미 자기자신의 길이를 저장하고 있음
first = len(nums) # O(1) : 리스트 객체는 이미 자기자신의 길이를 저장하고 있음
set_nums = set(nums) # O(N)
second = len(set_nums)
return (first != second)
Expand Down
15 changes: 15 additions & 0 deletions number-of-1-bits/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Bit Manipulation, Greedy
  • 설명: 주어진 코드에서 1의 개수를 세는 연산은 비트 조작 방식으로 수행되며(비트 연산 대체를 직접 구현) 비트 패턴을 다루는 패턴에 속한다. 또한 두 번째 방법은 각 비트를 차례로 확인하며 합산하는 일반적인 비트 조작 접근으로 분류된다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(1)

피드백: bin(n) 사용 또는 비트 연산으로 차수에 따라 1의 개수를 카운트한다.

개선 제안: 가독성/성능 측면에서 필요에 따라 비트 탐색 최적화 기법(Kernighan의 알고리즘) 도입 가능.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution:
def hammingWeight(self, n: int) -> int:
binary = bin(n)
return binary.count("1")

# bin() 을 못쓰는 경우의 풀이
class Solution:
def hammingWeight(self, n: int) -> int:
count = 0

while n > 0:
count += n % 2
n //=2

return count
16 changes: 16 additions & 0 deletions product-of-array-except-self/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Two Pointers, Hash Map / Hash Set, Greedy, Dynamic Programming, Divide and Conquer, Bit Manipulation, Sliding Window, Backtracking, Depth-First Search, Breadth-First Search, Union Find, Trie, Heap / Priority Queue, Monotonic Stack
  • 설명: 이 코드는 입력 배열의 각 원소에 대해 자신을 제외한 곱을 구하기 위해 좌우에서 누적 곱을 각각 계산한 뒤 곱하는 방식으로 결과를 구성한다. 보조 배열 하나로 좌측 누적곱과 우측 누적곱의 효과를 합성해 O(n)으로 해결하는 패턴이다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(1)

피드백: 두 패스로 왼쪽 곱과 오른쪽 곱을 합쳐 결과를 만든다.

개선 제안: 추가 배열 사용 없이도 가능하지만, 출력 배열은 이미 필요 공간이므로 현재 구현은 적절하다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
answer = [1] * len(nums)

# left -> right
for i in range(1, len(nums)):
answer[i] = answer[i-1] * nums[i-1] # 왼쪽에 있는 것들을 곱하자

# right -> left
right_product = 1
for i in range(len(nums)-1, -1, -1):
answer[i] = answer[i] * right_product
right_product = right_product * nums[i]


return answer
17 changes: 8 additions & 9 deletions top-k-frequent-elements/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Heap / Priority Queue, Hash Map / Hash Set
  • 설명: 해시맵으로 각 숫자의 빈도를 구하고, 최소 힙으로 상위 k개를 유지하는 방식으로 최빈 요소를 찾습니다. 이는 빈도 계산과 우선순위 큐를 이용한 부분 정렬의 조합입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n log k)
Space O(k + m)

피드백: 빈도 수를 기준으로 최소 힙을 유지해 메모리 사용을 제한한다.

개선 제안: 더 간단한 방법으로 정렬 기반 접근이나 파이프라인 최적화 고려 가능.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ def topKFrequent(self, nums: List[int], k: int) -> List[int]:
answer = []
count = dict()
heap = []
if len(nums) <= 1:
if len(nums) <= 1:
return nums
# O(N)
for num in nums:
# O(N)
for num in nums:
count[num] = count.get(num, 0) + 1
# heap 의 크기는 최대 k 로 제한함.

# heap 의 크기는 최대 k 로 제한함.
# unique 한 M개의 숫자를 선형 순회 O(M)
for num, freq in count.items():
if len(heap) < k:
if len(heap) < k:
heapq.heappush(heap, (freq, num)) # O(logK)
else:
else:
if heap[0][0] < freq:
heapq.heappop(heap) # O(logK)
heapq.heappush(heap, (freq, num)) # O(logK)
Expand All @@ -25,5 +25,4 @@ def topKFrequent(self, nums: List[int], k: int) -> List[int]:
k, v = heapq.heappop(heap)
answer.append(v)

return answer

return answer
6 changes: 3 additions & 3 deletions two-sum/freemjstudio.py

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🏷️ 알고리즘 패턴 분석

  • 패턴: Hash Map / Hash Set
  • 설명: 해당 코드는 한 숫자와 필요한 차이를 해시맵에 저장하고, 현재 숫자와의 차이가 이미 존재하는지 확인하여 정답을 찾는 방식으로 동작합니다. 이를 통해 탐색과 조회를 빠르게 수행하는 해시 맵 패턴이 적용됩니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(n)

피드백: 한 번의 순회로 답을 찾지만, 조건에 따라 반환 시점이 다를 수 있다.

개선 제안: 동일한 값의 인덱스가 필요한 경우 주의 필요.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
current_num = nums[i]
diff = target - current_num
if diff in hashmap.keys():
return [i, hashmap[diff]]
if diff in hashmap.keys():
return [i, hashmap[diff]]
hashmap[current_num] = i # store the index of current num

return answer
16 changes: 8 additions & 8 deletions valid-anagram/freemjstudio.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
첫번째 풀이
첫번째 풀이
시간 복잡도 : O(n log n)
"""

Expand All @@ -14,19 +14,19 @@ def isAnagram(self, s: str, t: str) -> bool:

class Solution:
def isAnagram(self, s: str, t: str) -> bool:
# 반례 : s = ab, t = a
# 반례 : s = ab, t = a
# 이 경우에는 t에 없는 b가 존재하므로 False를 반환해야 한다.
if len(s) != len(t):
return False
return False
counter = {}

for ch in s:
for ch in s:
counter[ch] = counter.get(ch, 0) + 1
for ch in t:

for ch in t:
if ch not in counter:
return False
return False
counter[ch] -= 1
if counter[ch] < 0:
return False
return False
return True
21 changes: 21 additions & 0 deletions valid-palindrome/freemjstudio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Solution:
def isPalindrome(self, s: str) -> bool:
characters = "abcdefghijklmnopqrstuvwxyz0123456789"
s = s.lower()

filtered = ""
for ch in s:
if ch in characters:
filtered += ch

n = len(filtered)
left = 0
right = n-1
while left <= n//2 and right >= n//2:
if filtered[left] == filtered[right]:
left += 1
right -= 1
else:
return False

return True
Loading