From 415d68ac9cf41dc8ba7c3fe92595ba43b3b73513 Mon Sep 17 00:00:00 2001 From: freemjstudio Date: Sat, 11 Jul 2026 16:58:46 +0900 Subject: [PATCH 1/4] Add week 03 solutions --- combination-sum/freemjstudio.py | 23 +++++++++++++++++++++++ number-of-1-bits/freemjstudio.py | 15 +++++++++++++++ valid-palindrome/freemjstudio.py | 21 +++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 combination-sum/freemjstudio.py create mode 100644 number-of-1-bits/freemjstudio.py create mode 100644 valid-palindrome/freemjstudio.py diff --git a/combination-sum/freemjstudio.py b/combination-sum/freemjstudio.py new file mode 100644 index 0000000000..d6824f6949 --- /dev/null +++ b/combination-sum/freemjstudio.py @@ -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 diff --git a/number-of-1-bits/freemjstudio.py b/number-of-1-bits/freemjstudio.py new file mode 100644 index 0000000000..ef95ab1dea --- /dev/null +++ b/number-of-1-bits/freemjstudio.py @@ -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 diff --git a/valid-palindrome/freemjstudio.py b/valid-palindrome/freemjstudio.py new file mode 100644 index 0000000000..cb93b4e4e9 --- /dev/null +++ b/valid-palindrome/freemjstudio.py @@ -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 From 5e30613e77b7a557847d4ee9c67b49a80bd1d973 Mon Sep 17 00:00:00 2001 From: freemjstudio Date: Sat, 11 Jul 2026 18:10:01 +0900 Subject: [PATCH 2/4] freemjstudio/decode-ways --- decode-ways/freemjstudio.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 decode-ways/freemjstudio.py diff --git a/decode-ways/freemjstudio.py b/decode-ways/freemjstudio.py new file mode 100644 index 0000000000..8d24a3421c --- /dev/null +++ b/decode-ways/freemjstudio.py @@ -0,0 +1,20 @@ +class Solution: + def numDecodings(self, s: str) -> int: + # invalid case + if s[0] == "0": + return 0 + + dp = [0] * (len(s)+1) # 앞에서부터 i개 문자를 해석하는 방법 + + dp[0] = 1 + dp[1] = 1 + for i in range(2, len(s)+1): + one_digit = s[i-1] + two_digits = int(s[i-2]) * 10 + int(s[i-1]) + if one_digit != '0': # 현재 숫자를 한자리로 해석하는 경우. (0 은 매칭되는 알파벳이 없으므로 제외) + dp[i] += dp[i-1] + + if 10 <= two_digits <= 26: # 현재 숫자를 바로 앞자리 숫자와 묶어서 두자리로 해석하는 경우 + dp[i] += dp[i-2] + + return dp[len(s)] \ No newline at end of file From dd1d3d75bb591e15042e8347aaa6d86bed2c8fa4 Mon Sep 17 00:00:00 2001 From: freemjstudio Date: Sat, 11 Jul 2026 18:12:42 +0900 Subject: [PATCH 3/4] Fix decode ways formatting --- decode-ways/freemjstudio.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/decode-ways/freemjstudio.py b/decode-ways/freemjstudio.py index 8d24a3421c..fb32dd1fa1 100644 --- a/decode-ways/freemjstudio.py +++ b/decode-ways/freemjstudio.py @@ -4,8 +4,8 @@ def numDecodings(self, s: str) -> int: if s[0] == "0": return 0 - dp = [0] * (len(s)+1) # 앞에서부터 i개 문자를 해석하는 방법 - + dp = [0] * (len(s)+1) # 앞에서부터 i개 문자를 해석하는 방법 + dp[0] = 1 dp[1] = 1 for i in range(2, len(s)+1): @@ -14,7 +14,7 @@ def numDecodings(self, s: str) -> int: if one_digit != '0': # 현재 숫자를 한자리로 해석하는 경우. (0 은 매칭되는 알파벳이 없으므로 제외) dp[i] += dp[i-1] - if 10 <= two_digits <= 26: # 현재 숫자를 바로 앞자리 숫자와 묶어서 두자리로 해석하는 경우 + if 10 <= two_digits <= 26: # 현재 숫자를 바로 앞자리 숫자와 묶어서 두자리로 해석하는 경우 dp[i] += dp[i-2] - - return dp[len(s)] \ No newline at end of file + + return dp[len(s)] From 9ee1be0c5137e6ddab9dc0bd5d21017178e680ac Mon Sep 17 00:00:00 2001 From: freemjstudio Date: Sat, 11 Jul 2026 18:33:56 +0900 Subject: [PATCH 4/4] freemjstudio/maximum-subarray --- maximum-subarray/freemjstudio.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 maximum-subarray/freemjstudio.py diff --git a/maximum-subarray/freemjstudio.py b/maximum-subarray/freemjstudio.py new file mode 100644 index 0000000000..24cbcce9ef --- /dev/null +++ b/maximum-subarray/freemjstudio.py @@ -0,0 +1,14 @@ +class Solution: + def maxSubArray(self, nums: List[int]) -> int: + n = len(nums) + if n == 1: + return nums[0] + + dp = [0] * n + dp[0] = nums[0] + # dp[i] = i에서 끝나는 부분 배열의 최대 합 + + for i in range(1, n): + dp[i] = max(nums[i], dp[i-1] + nums[i]) + + return max(dp)