diff --git a/3sum/pmjuu.py b/3sum/pmjuu.py new file mode 100644 index 000000000..acbd032c2 --- /dev/null +++ b/3sum/pmjuu.py @@ -0,0 +1,42 @@ +from typing import List + +class Solution: + def threeSum(self, nums: List[int]) -> List[List[int]]: + result = [] + nums.sort() # sort nums before using two-pointers + + for i, num in enumerate(nums): + # skip duplicated targets + if i > 0 and nums[i] == nums[i - 1]: + continue + + target = -num + left, right = i + 1, len(nums) - 1 + + while left < right: + if nums[left] + nums[right] == target: + result.append([num, nums[left], nums[right]]) + + # skip duplicated numbers ( ex. nums = [-3 0 0 0 3 3] ) + while left < right and nums[left] == nums[left + 1]: + left += 1 + while left < right and nums[right] == nums[right -1]: + right -= 1 + + left += 1 + right -= 1 + elif nums[left] + nums[right] < target: + left += 1 + else: + right -= 1 + + return result + + +# Time Complexity: O(n^2) +# - Sorting takes O(n log n). +# - The outer loop runs O(n) times, and the two-pointer approach inside runs O(n) for each iteration. +# - Combined, the overall time complexity is O(n^2). + +# Space Complexity: O(k) +# - The result list uses O(k) space, where k is the number of unique triplets in the output. diff --git a/climbing-stairs/pmjuu.py b/climbing-stairs/pmjuu.py new file mode 100644 index 000000000..53d7fa5b6 --- /dev/null +++ b/climbing-stairs/pmjuu.py @@ -0,0 +1,30 @@ +class Solution: + def climbStairs(self, n: int) -> int: + # dp[i] represents the number of distinct ways to climb to the ith step. + # Base cases: + # - There is 1 way to reach step 0 (doing nothing). + # - There is 1 way to reach step 1 (a single step). + dp = [0] * (n + 1) + dp[0], dp[1] = 1, 1 + + for i in range(2, n + 1): + dp[i] = dp[i - 1] + dp[i - 2] + + return dp[n] + +# Complexity +# - time: O(n) +# - space: O(n) + +class Solution: + def climbStairs(self, n: int) -> int: + prev, curr = 1, 1 + + for _ in range(2, n + 1): + prev, curr = curr, prev + curr + + return curr + +# Complexity +# - time: O(n) +# - space: O(1) diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/pmjuu.py b/construct-binary-tree-from-preorder-and-inorder-traversal/pmjuu.py new file mode 100644 index 000000000..60a0f91c4 --- /dev/null +++ b/construct-binary-tree-from-preorder-and-inorder-traversal/pmjuu.py @@ -0,0 +1,36 @@ +from typing import List, Optional + +# 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: + def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + inorder_map = {value: idx for idx, value in enumerate(inorder)} + self.preorder_idx = 0 + + def helper(left: int, right: int) -> Optional[TreeNode]: + if left > right: + return None + + root_val = preorder[self.preorder_idx] + self.preorder_idx += 1 + + root = TreeNode(root_val) + root.left = helper(left, inorder_map[root_val] - 1) + root.right = helper(inorder_map[root_val] + 1, right) + + return root + + return helper(0, len(inorder) - 1) + + +# Time Complexity: O(n) +# - Each node is visited exactly once in preorder, and the dictionary lookup in inorder_map takes O(1) per node. + +# Space Complexity: O(n) +# - The hash map (inorder_map) uses O(n) space. +# - The recursion stack uses up to O(h) space, where h is the height of the tree (O(n) in the worst case, O(log n) for a balanced tree). diff --git a/decode-ways/pmjuu.py b/decode-ways/pmjuu.py new file mode 100644 index 000000000..28a2a74fc --- /dev/null +++ b/decode-ways/pmjuu.py @@ -0,0 +1,31 @@ +class Solution: + def numDecodings(self, s: str) -> int: + if s[0] == "0": + return 0 + + prev, curr = 1, 1 + + for i in range(1, len(s)): + temp = curr + + if s[i] == "0": + if s[i - 1] in ("1", "2"): + curr = prev + else: + return 0 + else: + two_num = int(s[i - 1] + s[i]) + is_two_num_decoded = 10 <= two_num <= 26 + if is_two_num_decoded: + curr += prev + + prev = temp + + return curr + + +# Time Complexity: O(n) +# - The loop iterates through the string once, where n is the length of the string. + +# Space Complexity: O(1) +# - Only two variables (prev and curr) are used, independent of the input size. diff --git a/valid-anagram/pmjuu.py b/valid-anagram/pmjuu.py new file mode 100644 index 000000000..e325494f2 --- /dev/null +++ b/valid-anagram/pmjuu.py @@ -0,0 +1,11 @@ +from collections import Counter + +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + return Counter(s) == Counter(t) + +# Python의 collections.Counter는 유니코드 문자를 지원합니다. +# 시간복잡도: O(n) + # Counter는 해시 테이블 기반의 연산으로 동작하며, 각 문자열의 문자를 한 번씩 순회합니다. +# 공간복잡도: O(n) + # 각 문자열에 대해 Counter 객체를 생성하므로, 최악의 경우 각 문자마다 빈도를 저장하는 데 O(n) 크기의 해시테이블이 필요합니다.