File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -38,3 +38,42 @@ def dfs(target_list, start_i):
3838 dfs ([], 0 )
3939
4040 return results
41+
42+
43+ # 7기 풀이
44+ # T: target 수, C: candidates의 최소값일 때,
45+ # 시간 복잡도: O(n ^ (T/C))
46+ # - 최악의 경우는 가장 작은 candidate로 target을 만드는 횟수만큼 candidates를 탐색할 때이다. (dominant)
47+ # - sorting은 O(n log n)이며, 무시 가능
48+ # 공간 복잡도: O(T/C)
49+ # - dfs의 call stack의 깊이는 T/C가 최대 깊이
50+ # - result의 조합 또한 T/C가 최대 길이
51+ class Solution :
52+ # DFS로 문제를 풀이하며 조건에 맞춰 가지치기가 필요한 문제
53+ # 문제 풀이 편의를 위해 candidates를 sorting한 후 풀이를 한다.
54+ def combinationSum (self , candidates : List [int ], target : int ) -> List [List [int ]]:
55+ candidates .sort ()
56+ results = []
57+
58+ def dfs (target , result ):
59+ if target == 0 :
60+ # 더이상 target을 만드는데 숫자가 필요하지 않으므로
61+ # 정답 array에 deepcopy하여 저장
62+ results .append (result [:])
63+ return
64+
65+ for candidate in candidates :
66+ if candidate > target :
67+ # 후보 수가 target보다 크면 그 이후의 수는 더이상 탐색하지 않아도 된다
68+ return
69+ if result and candidate < result [- 1 ]:
70+ # 후보 수가 result의 마지막 수보다 크면 skip한다(result 내 숫자들도 작은 수부터 저장되게 함)
71+ continue
72+ result .append (candidate )
73+ # target에서 candidate를 뺀 만큼 다음 stack 계산을 한다.
74+ dfs (target - candidate , result )
75+ result .pop ()
76+
77+ dfs (target , [])
78+
79+ return results
Original file line number Diff line number Diff line change 1+ # 7기 풀이
2+ # 시간복잡도: O(n)
3+ # - memoization을 하기 때문에 각 인덱스 별로 가능한 수를 계산할 때 한 번 씩만 계산
4+ # 공간복잡도: O(n)
5+ # - 문자열의 길이만큼 memo 값이 늘어남
6+ class Solution :
7+ # DP를 이용해 문제를 풀면 된다.
8+ # 각 인덱스로 별로 문자열을 잘랐을 때의 가능한 디코딩 방법 수를 memo한다
9+ def numDecodings (self , s : str ) -> int :
10+ len_s = len (s )
11+ memo = {}
12+
13+ def dfs (index ):
14+ if index == len_s : # 끝까지 탐색했다면 가능한 디코딩 방법이므로 1을 return
15+ return 1
16+
17+ if s [index ] == '0' : # 현재 index의 문자가 '0'이면 해당 방법은 디코딩이 불가한 것으로 판단 0을 return
18+ return 0
19+
20+ if index in memo : # 이미 저장되어 있다면 memo 값을 return
21+ return memo [index ]
22+
23+ result = dfs (index + 1 ) # index로부터 한 자리 수만 계산할 때, 다음 계산은 index + 1이 된다
24+
25+ if (
26+ index + 1 < len_s
27+ and int (s [index :index + 2 ]) <= 26
28+ ): # index~index+1의 문자열이 26보다 작은 두 자리 수일 때만 index + 2번째 계산을 한다
29+ result += dfs (index + 2 )
30+
31+ memo [index ] = result # memoization을 한다
32+ return result
33+
34+ return dfs (0 )
Original file line number Diff line number Diff line change 1+ # 7기 풀이
2+ # 시간 복잡도: O(n)
3+ # - nums의 모든 요소를 탐색하기 때문에 nums의 길이에 관련되어 있음
4+ # 공간 복잡도: O(1)
5+ # - 변수 이외에 객체를 쓰지 않았기 때문에 공간 복잡도는 O(1)이다(input 길이와 상관 없음)
6+ class Solution :
7+ def maxSubArray (self , nums : List [int ]) -> int :
8+ curr_sum = nums [0 ]
9+ max_sum = nums [0 ]
10+
11+ for i in range (1 , len (nums )):
12+ # 1. (현재까지의 합과 i의 요소를 더한 값)과 i의 요소를 서로 비교하여 지금까지의 합을 업데이트한다.
13+ # - 자기 자신만으로도 이전 합들보다 크다면 이전 합들은 의미가 없어짐을 얘기
14+ curr_sum = max (nums [i ], curr_sum + nums [i ])
15+
16+ # 현재까지의 합과 이전 max 합을 비교하여 업데이트
17+ max_sum = max (max_sum , curr_sum )
18+
19+ return max_sum
Original file line number Diff line number Diff line change @@ -20,3 +20,27 @@ def hammingWeight(self, n: int) -> int:
2020 n = n // 2
2121
2222 return bits_sum
23+
24+
25+ # 7기 풀이
26+ # 시간 복잡도: O(log n)
27+ # - 2로 계속 나누고, 이는 2진수 자릿수 만큼 반복
28+ # 공간 복잡도: O(1)
29+ # - 고정된 변수(quotient, remainder)만 사용
30+ class Solution :
31+ def hammingWeight (self , n : int ) -> int :
32+ # 10진수를 2진수로 변환하는 과정은 2로 계속 나누면서 그 나머지 값들을 순차적으로 나열하는 것이다.
33+ # 이 때 문자열로 만들지 않고 바로 result에 더해가면 답이 될 수 있음
34+ result = 0
35+
36+ while n > 0 :
37+ # 몫과 나머지 계산
38+ quotient , remainder = n // 2 , n % 2
39+
40+ # 나머지는 result에 더함
41+ result += remainder
42+
43+ # 몫은 다음 피제수로 사용
44+ n = quotient
45+
46+ return result
Original file line number Diff line number Diff line change @@ -24,3 +24,33 @@ def isPalindrome(self, s: str) -> bool:
2424 return False
2525
2626 return True
27+
28+
29+ # 7기 풀이
30+ # 시간 복잡도: O(n)
31+ # - 문자열 s의 전체 문자를 순회할 때 길이 n만큼의 시간 소요
32+ # 공간 복잡도: O(1)
33+ # - start, end 등의 변수만 사용
34+
35+ class Solution :
36+ def isPalindrome (self , s : str ) -> bool :
37+ # two pointer로 각 문자열을 비교하며 palindrome인지 체크한다.
38+ # 해당 문제의 조건 중 하나가 alphanumeric한 문자만 체크하는 것
39+ start , end = 0 , len (s ) - 1
40+
41+ # 양 끝의 포인터 인덱스가 같아지기 전까지 루프를 돌린다.
42+ while start < end :
43+ if not s [start ].isalnum ():
44+ # s[start] 문자가 alphanumeric하지 않은 경우엔 start 포인터를 오른쪽으로 한 칸 이동
45+ start += 1
46+ continue
47+ if not s [end ].isalnum ():
48+ # s[end] 문자가 alphanumeric하지 않은 경우엔 end 포인터를 왼쪽으로 한 칸 이동
49+ end -= 1
50+ continue
51+ if s [start ].lower () != s [end ].lower ():
52+ # 두 문자의 lowercase가 동일하지 않은 경우에는 palindrome이 아니므로 False로 early return 해준다.
53+ return False
54+ start , end = start + 1 , end - 1
55+ # while 루프가 다 돌았다면 조건에 걸리지 않고 palindrome임을 충족하므로 True를 return
56+ return True
You can’t perform that action at this time.
0 commit comments