diff --git a/combination-sum/ZetBe.py b/combination-sum/ZetBe.py new file mode 100644 index 0000000000..613fe652ee --- /dev/null +++ b/combination-sum/ZetBe.py @@ -0,0 +1,30 @@ +''' +문제: target이 될 때까지 candidates의 수를 더하는 모든 조합을 구하라. +풀이: 백트래킹을 이용하여 조합을 구한다. 만약 현재 합이 target과 같다면 결과 리스트에 추가하고, 작다면 후보군을 순회하며 재귀적으로 탐색한다. +시간복잡도: O(N^T), N은 후보군의 수, T는 target의 값 + 최악의 경우, 후보군의 수 N과 target의 값 T에 따라 모든 조합을 탐색해야 하므로 시간복잡도는 O(N^T)이다. +공간복잡도: O(T) + 재귀 호출 스택과 현재 조합을 저장하는 데 최대 T개의 공간이 필요하므로 공간복잡도는 O(T)이다. +사용한 자료구조: 리스트 +참고로 함수의 호출 깊이는 target/min(candidates)로 제한된다. +''' + + +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + candidates.sort() + s, now = [], [] + + def find(start, score): + if score == target: + s.append(now[:]) + elif score < target: + for i in range(start, len(candidates)): + n = candidates[i] + now.append(n) + find(i, score+n) + now.pop() + find(0, 0) + return s + + diff --git a/decode-ways/ZetBe.py b/decode-ways/ZetBe.py new file mode 100644 index 0000000000..3add825f68 --- /dev/null +++ b/decode-ways/ZetBe.py @@ -0,0 +1,85 @@ +''' +문제: 숫자로 이루어진 문자열이 주어졌을 때, 이를 알파벳으로 디코딩하는 방법의 수를 구하는 문제(여기서 1은 'A', 2는 'B', ..., 26은 'Z'에 해당). +풀이: 동적 계획법을 사용하여 각 위치까지의 디코딩 방법의 수를 계산 + 1. dp[i]를 문자열의 i번째 문자까지 디코딩하는 방법의 수라고 정의 + 2. 문자열의 i번째 문자가 '0'인 경우, 이전 문자가 '1' 또는 '2'인 경우에만 유효한 디코딩이 가능하므로 dp[i] = dp[i-2] + 3. 문자열의 i번째 문자와 이전 문자를 합쳐서 10~26 사이의 숫자가 되는 경우, dp[i] = dp[i-1] + dp[i-2] + 4. 그 외의 경우에는 dp[i] = dp[i-1] +시간복잡도: O(n) + 문자열을 한 번 순회하며 dp 배열을 채우므로 전체 시간복잡도는 O(n)이다. +공간복잡도: O(n) + dp 배열을 사용하므로 전체 공간복잡도는 O(n)이다. +사용한 자료구조: 리스트 +''' + + +class Solution: + def numDecodings(self, s: str) -> int: + string = list(s) + n = len(string) + dp = [0 for i in range(n)] + if string[0] == '0': + return 0 + if n == 1: + return 1 + if n == 2: + if 11 <= int(s) <= 19 or 21 <= int(s) <= 26: + return 2 + elif int(s) == 10 or int(s) == 20: + return 1 + elif '0' in string: + return 0 + else: + return 1 + dp[0] = 1 + if string[1] == '0' and 3 <= int(string[0]): + return 0 + if 11 <= int(string[0])*10 + int(string[1]) <= 19 or 21 <= int(string[0])*10 + int(string[1]) <= 26: + dp[1] = 2 + else: + dp[1] = 1 + + for i in range(2, n): + if string[i] == '0' and (3 <= int(string[i-1]) or int(string[i-1]) == 0): + return 0 + if 11 <= int(string[i-1])*10 + int(string[i]) <= 19 or 21 <= int(string[i-1])*10 + int(string[i]) <= 26: + dp[i] = dp[i-2] + dp[i-1] + elif int(string[i-1])*10 + int(string[i]) == 10 or int(string[i-1])*10 + int(string[i]) == 20: + dp[i] = dp[i-2] + else: + dp[i] += dp[i-1] + + return dp[n-1] + + +''' +너무 복잡하게 풀었기 때문에 ai에게 간결한 풀이를 알려달라해서 공유드립니다 + +class Solution: + def numDecodings(self, s: str) -> int: + if not s or s[0] == '0': + return 0 + + n = len(s) + # dp[i] : s의 앞 i글자를 해석하는 방법의 수 + dp = [0] * (n + 1) + + # 초기값 설정 (빈 문자열은 1가지 방법, 첫 글자는 위에서 0체크 했으므로 1가지) + dp[0] = 1 + dp[1] = 1 + + for i in range(2, n + 1): + # 1. 한 자리 숫자 해석 (1~9) + # 현재 숫자(s[i-1])가 '0'이 아니면, 이전 상태(dp[i-1])를 계승 + if s[i-1] != '0': + dp[i] += dp[i-1] + + # 2. 두 자리 숫자 해석 (10~26) + # 이전 숫자와 현재 숫자를 합쳐서 10~26 사이라면, 전전 상태(dp[i-2])를 더함 + two_digit = int(s[i-2 : i]) + if 10 <= two_digit <= 26: + dp[i] += dp[i-2] + + return dp[n] +''' + diff --git a/maximum-subarray/ZetBe.py b/maximum-subarray/ZetBe.py new file mode 100644 index 0000000000..a466837134 --- /dev/null +++ b/maximum-subarray/ZetBe.py @@ -0,0 +1,36 @@ +''' +문제: 최대 부분 배열의 합을 구하는 문제 +풀이: + 1. 배열의 모든 수가 음수인 경우, 가장 큰 수를 반환 + 2. 배열의 처음부터 양수가 나올 때까지 인덱스를 이동 + 3. 양수가 나온 이후부터는 현재 합이 양수인 동안은 계속 더하고, 음수가 되면 다시 양수를 찾음 + 4. 매 단계마다 최대 합을 갱신 +시간복잡도: O(n) + 배열을 한 번 순회하며 최대 부분 배열의 합을 계산하므로 전체 시간복잡도는 O(n)이다. +공간복잡도: O(1) + 추가적인 공간을 사용하지 않으므로 전체 공간복잡도는 O(1)이다. +''' + + +class Solution: + def maxSubArray(self, nums: List[int]) -> int: + n = len(nums) + answ = 0 + if max(nums) <= 0: + return max(nums) + i = 0 + while nums[i] < 0: + i += 1 + now = 0 + while i < n: + if now > 0 and i < n: + now += nums[i] + i += 1 + else: + while now <= 0 and i < n: + now = nums[i] + i += 1 + answ = max(answ, now) + + return answ + diff --git a/number-of-1-bits/ZetBe.py b/number-of-1-bits/ZetBe.py new file mode 100644 index 0000000000..dc0e285b89 --- /dev/null +++ b/number-of-1-bits/ZetBe.py @@ -0,0 +1,28 @@ +''' +문제: 정수 n이 주어졌을 때, n의 이진 표현에서 1의 개수를 반환하는 함수를 작성하세요. +풀이: 2의 거듭제곱 수들을 미리 계산해두고, n에서 큰 수부터 빼가며 1의 개수를 세는 방식으로 풀이 +시간복잡도: O(log n) + 2의 거듭제곱 수들을 미리 계산하는데 O(log n)이 걸리고, n에서 큰 수부터 빼가며 1의 개수를 세는 데도 O(log n)이 걸리므로 전체 시간복잡도는 O(log n)이다. +공간복잡도: O(log n) + 2의 거듭제곱 수들을 저장하는 리스트를 사용하므로 전체 공간복잡도는 O(log n)이다. +사용한 자료구조: 리스트 +''' + + +class Solution: + def hammingWeight(self, n: int) -> int: + b = [] + now = 1 + answ = 0 + for i in range(35): + b.append(now) + now *= 2 + + num = n + for i in range(34, -1, -1): + if num >= b[i]: + num -= b[i] + answ += 1 + return answ + + diff --git a/valid-palindrome/ZetBe.py b/valid-palindrome/ZetBe.py new file mode 100644 index 0000000000..7875427de7 --- /dev/null +++ b/valid-palindrome/ZetBe.py @@ -0,0 +1,29 @@ +''' +문제: 유효한 팰린드롬, 해당 문자열이 팰린드롬인지 확인하는 문제 +풀이: 대소문자 구분 없이 알파벳과 숫자만을 고려하여 팰린드롬인지 확인 +시간복잡도: O(n) + 문자열을 한 번 순회하며 유효한 문자만 추출하고, 다시 한번 순회하며 팰린드롬 여부를 확인하므로 전체 시간복잡도는 O(n)이다. +공간복잡도: O(n) + 유효한 문자를 저장하기 위한 추가 리스트를 사용하므로 전체 공간복잡도는 O(n)이다. +사용한 자료구조: 리스트 +''' + + +class Solution: + def isPalindrome(self, s: str) -> bool: + string = [] + for i in s: + if 65 <= ord(i) <= 90: + string.append(i) + elif 97 <= ord(i) <= 122: + string.append(chr(ord(i)-32)) + elif 48 <= ord(i) <= 57: + string.append(i) + + + for i in range(len(string)): + if string[i] != string[len(string)-1-i]: + return False + return True + +