diff --git a/combination-sum/thispath98.py b/combination-sum/thispath98.py new file mode 100644 index 000000000..8a1904c18 --- /dev/null +++ b/combination-sum/thispath98.py @@ -0,0 +1,41 @@ +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + """ + Intuition: + 리스트의 각 원소는 중복해서 사용할 수 있다. + 그렇다면 target은 재귀적으로 원소를 사용해서 + 모든 경우의 수를 탐색한다. + + Time Complexity: + O(N^2 log N): + 초기에 리스트의 원소를 정렬하는 데에 O(N log N)이 소요된다. + 또한, 재귀 함수는 최대 N번 호출될 수 있으며 + 각 재귀 함수에서는 정렬하여 세트에 추가하는 경우 + O(N log N)이 소요되고, + N개의 원소에 대해 for문을 반복한다. + 따라서 O(N^2 log N)의 시간복잡도가 소요된다. + + Space Complexity: + O(N): + 최악의 경우 answer set에 대략 N개의 tuple이 저장된다. + 따라서 O(N)의 공간복잡도가 소요된다. + """ + candidates.sort() # O(N log N) + answer_set = set() + + + def dfs(n, arr): + if n == 0: + answer_set.add(tuple(sorted(arr))) # O(N log N) + return + + for candidate in candidates: # O(N) + if n >= candidate: + arr.append(candidate) + dfs(n - candidate, arr) + arr.pop() + + + dfs(target, []) # O(N) + answer = list(answer_set) + return answer diff --git a/maximum-subarray/thispath98.py b/maximum-subarray/thispath98.py new file mode 100644 index 000000000..1cae0041b --- /dev/null +++ b/maximum-subarray/thispath98.py @@ -0,0 +1,37 @@ +class Solution: + def maxSubArray(self, nums: List[int]) -> int: + """ + Intuition: + 이전까지의 누적합에서 현재 원소를 추가할지 말지에 대한 + 결정을 매 iteration마다 반복한다. + 현재 원소를 추가했을 경우(누적합 + 현재 원소)와 + 현재 원소를 시작으로 하는 경우(현재 원소)를 비교하여 + dp 배열을 갱신한다. + + Time Complexity: + O(N): + 리스트를 1번 순회하며 답을 찾으므로, + O(N)의 시간복잡도가 소요된다. + + Space Complexity: + O(N): + dp 배열에 N개의 time step을 저장하므로 + O(N)의 공간복잡도가 소요된다. + + Key takeaway: + 초기에는 two pointer 방식을 생각했으나 + 해결을 하지 못해서 답안을 확인했다. + O(N)의 시간복잡도를 가지는 경우, DP도 풀이가 + 될 수 있음을 인지하자. + """ + dp = [0 for _ in nums] + dp[0] = nums[0] + for i in range(1, len(nums)): + cumsum = dp[i - 1] + nums[i] + cur = nums[i] + if cumsum > cur: + dp[i] = cumsum + else: + dp[i] = cur + + return max(dp) diff --git a/product-of-array-except-self/thispath98.py b/product-of-array-except-self/thispath98.py new file mode 100644 index 000000000..c74d6616a --- /dev/null +++ b/product-of-array-except-self/thispath98.py @@ -0,0 +1,35 @@ +class Solution: + def productExceptSelf(self, nums: List[int]) -> List[int]: + """ + Intuition: + i번째 인덱스의 값을 계산하기 위해서는 + 0 ~ i-1 까지의 값과 i+1 ~ N 까지의 값을 모두 곱해야 한다. + 이의 누적곱을 저장하여, 계산한다. + + Time Complexity: + O(N): + 리스트를 1번 순회하며 답을 찾으므로, + O(N)의 시간복잡도가 소요된다. + + Space Complexity: + O(N): + forward 배열과 backward 배열에 N개의 원소를 저장하므로 + O(N)의 공간복잡도가 소요된다. + + Key takeaway: + 스캔하여 값을 저장해두는 방식을 숙지하자. + """ + for_val = 1 + back_val = 1 + forward = [] + backward = [] + for i in range(len(nums)): + forward.append(for_val) + backward.append(back_val) + + for_val *= nums[i] + back_val *= nums[-(i + 1)] + backward = backward[::-1] + + answer = [forward[i] * backward[i] for i in range(len(nums))] + return answer diff --git a/reverse-bits/thispath98.py b/reverse-bits/thispath98.py new file mode 100644 index 000000000..38be2e89a --- /dev/null +++ b/reverse-bits/thispath98.py @@ -0,0 +1,26 @@ +class Solution: + def reverseBits(self, n: int) -> int: + """ + Intuition: + 비트를 역순으로 순회한다. + answer에는 최대값(2^31)부터 최소값(2^0)으로 감소하는 + 방식으로 업데이트한다. + + Time Complexity: + O(N): + n을 1번 순회하며 답을 찾으므로, + O(N)의 시간복잡도가 소요된다. + + Space Complexity: + O(1): + answer에 값을 업데이트 하므로, 상수의 + 공간복잡도가 소요된다. + + Key takeaway: + 숫자를 binary string으로 만드는 bin() 메소드를 + 알게 되었다. + """ + answer = 0 + for i, bit in enumerate(bin(n)[2:][::-1]): + answer += int(bit) * 2 ** (31 - i) + return answer diff --git a/two-sum/thispath98.py b/two-sum/thispath98.py new file mode 100644 index 000000000..cca31e787 --- /dev/null +++ b/two-sum/thispath98.py @@ -0,0 +1,23 @@ +class Solution: + def twoSum(self, nums: List[int], target: int) -> List[int]: + """ + Intuition: + 기존에 풀었던 3sum 문제와 유사하게, + 해시에 현재 숫자와 더해서 target이 되는 값을 찾는다. + 만약 없을 경우, 해시에 현재 값과 인덱스를 저장한다. + + Time Complexity: + O(N): + 해시는 접근하는 데에 O(1)이 소요되고, + 총 N번 반복해야 하므로 시간복잡도는 O(N)이다. + + Space Complexity: + O(N): + 최악의 경우 해시에 N개의 숫자와 인덱스를 저장해야 한다. + """ + complement_dict = {} + for i, num in enumerate(nums): + if target - num in complement_dict: + return [complement_dict[target - num], i] + else: + complement_dict[num] = i