diff --git a/3sum/hu6r1s.py b/3sum/hu6r1s.py new file mode 100644 index 000000000..2bd132c11 --- /dev/null +++ b/3sum/hu6r1s.py @@ -0,0 +1,28 @@ +class Solution: + """ + 1. 3 way for문으로 돌아가면서 0인 합을 찾는 방법 + - O(n^3)으로 시간초과 + 2. 투포인터 + - 정렬 후 투포인터를 이용하여 중복 제거와 최적화를 동시에 수행 + - O(n^2) + 공간 복잡도는 둘다 O(1) + """ + def threeSum(self, nums: List[int]) -> List[List[int]]: + result = set() + nums.sort() + + for i in range(len(nums)): + left, right = i + 1, len(nums) - 1 + while left < right: + total = nums[i] + nums[left] + nums[right] + + if total == 0: + result.add((nums[i], nums[left], nums[right])) + left += 1 + right -= 1 + elif total < 0: + left += 1 + else: + right -= 1 + + return list(result) diff --git a/climbing-stairs/hu6r1s.py b/climbing-stairs/hu6r1s.py new file mode 100644 index 000000000..38f99d578 --- /dev/null +++ b/climbing-stairs/hu6r1s.py @@ -0,0 +1,25 @@ +class Solution: + """ + 1일 때, 1 step -> 1개 + 2일 때, 1 + 1, 2 -> 2개 + 3일 때, 1 + 1 + 1, 1 + 2, 2 + 1 -> 3개 + 4일 때, 1 + 1 + 1 + 1, 1 + 1 + 2, 1 + 2 + 1, 2 + 1 + 1, 2 + 2 -> 5개 + 5일 때, 1 + 1 + 1 + 1 + 1, 1 + 1 + 1 + 2, 1 + 1 + 2 + 1, 1 + 2 + 1 + 1, 2 + 1 + 1 + 1, 1 + 2 + 2, 2 + 1 + 2, 2 + 2 + 1 -> 8개 + 순서대로 봤을 때, 이전 값과 그 이전 값의 합이 현재 개수이다. + 이를 점화식으로 봤을 때, dp[i] = d[i - 1] + dp[i - 2]가 된다. + + - Time Complexity: O(n) + - 1부터 n까지 한 번씩 반복하므로 선형 시간 + - Space Complexity: O(n) + - dp 배열에 n개의 값을 저장하므로 선형 공간 사용 + """ + def climbStairs(self, n: int) -> int: + if n == 1: + return n + + dp = [0] * n + dp[0] = 1 + dp[1] = 2 + for i in range(2, n): + dp[i] = dp[i - 1] + dp[i - 2] + return dp[-1] diff --git a/product-of-array-except-self/hu6r1s.py b/product-of-array-except-self/hu6r1s.py new file mode 100644 index 000000000..56a01fe5f --- /dev/null +++ b/product-of-array-except-self/hu6r1s.py @@ -0,0 +1,34 @@ +import math + +class Solution: + """ + 1. 인덱스 슬라이싱을 활용한 풀이 + - 인덱스 슬라이싱을 활용하여 해당 인덱스를 제외한 나머지 원소들의 곲을 math.prod()를 이용하여 배열에 삽입 + - 시간초과 O(n^2) + 2. DP Bottom Up 방식으로 풀이 + - 인덱스 i에 대한 왼쪽 부분과 오른쪽 부분의 곱을 계산하는 방식 + - 시간 복잡도 O(n) + - 공간 복잡도 O(1) + """ + # 1번 풀이 + # def productExceptSelf(self, nums: List[int]) -> List[int]: + # answer = [1] * len(n) + + # for i in range(len(nums)): + # answer.append(math.prod(nums[:i] + nums[i+1:])) + + # return answer + + def productExceptSelf(self, nums: List[int]) -> List[int]: + dp = [1] * len(nums) + + left = 1 + for i in range(len(nums)): + dp[i] = left + left *= nums[i] + + right = 1 + for i in range(len(nums) - 1, -1, -1): + dp[i] *= right + right *= nums[i] + return dp diff --git a/valid-anagram/hu6r1s.py b/valid-anagram/hu6r1s.py new file mode 100644 index 000000000..6e66255c7 --- /dev/null +++ b/valid-anagram/hu6r1s.py @@ -0,0 +1,33 @@ +from collections import defaultdict + +class Solution: + """ + 1. Counter를 이용한 풀이 + - Counter로 풀이하였으나 s, t 길이가 서로 다를 때 해결되지 않음 + 2. defaultdict 활용 풀이 + - 똑같이 개수 세고 제외 + + TC + - s의 길이: n, t의 길이: n (조건상 같거나 비교 가능한 길이) + - 첫 번째 for 루프: O(n) → s의 모든 문자를 순회 + - 두 번째 for 루프: O(n) → t의 모든 문자를 순회 + - 총 시간 복잡도 = O(n) + + SC + - counter는 알파벳 개수를 세는 용도로만 사용됨 + - 공간 복잡도 = O(1) + """ + def isAnagram(self, s: str, t: str) -> bool: + counter = defaultdict(int) + + for i in s: + counter[i] += 1 + + for i in t: + if i not in counter: + return False + counter[i] -= 1 + + if counter[i] == 0: + del counter[i] + return False if counter else True diff --git a/validate-binary-search-tree/hu6r1s.py b/validate-binary-search-tree/hu6r1s.py new file mode 100644 index 000000000..75c3769ef --- /dev/null +++ b/validate-binary-search-tree/hu6r1s.py @@ -0,0 +1,21 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + """ + TC: O(n) + SC: 최악의 경우 -> O(n), 평균 -> O(log n) + - 트리가 균일할 경우 평균의 복잡도가 나오고 + - 한쪽이 치우친 경우 최악의 경우로 나온다. + """ + def isValidBST(self, root: Optional[TreeNode]) -> bool: + def validate(node, left, right): + if not node: + return True + if not (left < node.val < right): + return False + return validate(node.left, left, node.val) and validate(node.right, node.val, right) + return validate(root, float("-inf"), float("inf"))