From 2ef062cf3b8545f0828b41c0ca8b6aee6e2eb38f Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:20:39 +0900 Subject: [PATCH 1/8] add solution: valid-anagram --- valid-anagram/dusunax.py | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 valid-anagram/dusunax.py diff --git a/valid-anagram/dusunax.py b/valid-anagram/dusunax.py new file mode 100644 index 000000000..8607d4394 --- /dev/null +++ b/valid-anagram/dusunax.py @@ -0,0 +1,44 @@ +''' +# Leetcode 242. Valid Anagram + +use `Counter` to (1)compare the frequency of characters in both strings, and (2)try to compare the frequency more efficiently. ๐Ÿ” + +## Time and Space Complexity + +``` +TC: O(n) +SC: O(n) +``` + +### A. use frequency object + +#### TC is O(n): +- iterating through the strings just once to compare the frequency of characters. O(n) + +#### SC is O(n): +- creating a new string `converted_s` to store the + +### B. use Counter more efficiently + +#### TC is O(n): +- iterating through the strings just once to compare the frequency of characters. O(n) + +#### SC is O(n): +- creating a new string `converted_s` to store the +''' +class Solution: + def isAnagramA(self, s: str, t: str) -> bool: + if len(s) != len(t): + return False + + frequency = Counter(s) # SC: O(n) + + for char in t: # TC: O(n) + if char not in frequency or frequency[char] == 0: # TC: O(1) + return False + frequency[char] -= 1 + + return True + + def isAnagramB(self, s: str, t: str) -> bool: + return Counter(s) == Counter(t) # TC: O(n), SC: O(n) \ No newline at end of file From 6693c07be43c7496aa7135f468951ccf553dbf2a Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:24:48 +0900 Subject: [PATCH 2/8] =?UTF-8?q?fix:=20=EB=A6=B0=ED=8A=B8=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=ED=95=B4=EA=B2=B0=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EA=B0=9C=ED=96=89=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- valid-anagram/dusunax.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/valid-anagram/dusunax.py b/valid-anagram/dusunax.py index 8607d4394..bf785ee8a 100644 --- a/valid-anagram/dusunax.py +++ b/valid-anagram/dusunax.py @@ -41,4 +41,4 @@ def isAnagramA(self, s: str, t: str) -> bool: return True def isAnagramB(self, s: str, t: str) -> bool: - return Counter(s) == Counter(t) # TC: O(n), SC: O(n) \ No newline at end of file + return Counter(s) == Counter(t) # TC: O(n), SC: O(n) From 1a555d60263a56802408543ef8f3d5affb8d9bc7 Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:20:07 +0900 Subject: [PATCH 3/8] add solution: climbing-stairs --- climbing-stairs/dusunax.py | 71 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 climbing-stairs/dusunax.py diff --git a/climbing-stairs/dusunax.py b/climbing-stairs/dusunax.py new file mode 100644 index 000000000..ea378a3a1 --- /dev/null +++ b/climbing-stairs/dusunax.py @@ -0,0 +1,71 @@ +''' +# Leetcode 70. Climbing Stairs + +use `dynamic programming` to solve the problem. + +1. Bottom-up approach +2. Top-down approach + +## Time and Space Complexity + +### 1. Bottom-up approach + +``` +TC: O(n) +SC: O(1) +``` + +#### TC is O(n): +- iterating with a for loop. O(n) + +#### SC is O(1): +- using a constant space to store the previous two steps. O(1) + +### 2. Top-down approach + +``` +TC: O(n) +SC: O(n) +``` + +#### TC is O(n): +- performing a recursive call for each step. O(n) + +#### SC is O(n): +- using a memoization object to store the previous two steps. O(n) +''' + +class Solution: + ''' + 1. Bottom-up approach + ''' + def climbStairsLoop(self, n: int) -> int: + if n == 1 or n == 2: + return n + + # SC: O(1) + prev2 = 1 # ways to step 0 + prev1 = 1 # ways to step 1 + + for i in range(3, n + 1): # TC: O(n) + current = prev1 + prev2 # ways to (n-1) + (n-2) + prev2 = prev1 + prev1 = current + + return prev1 + + ''' + 2. Top-down approach + ''' + def climbStairsRecursive(self, n: int) -> int: + memo = {} # SC: O(n) + + def dp(step: int, memo: int) -> int: # TC: O(n) + if step == 1 or step == 2: + memo[step] = step + if step not in memo: + memo[step] = dp(step - 1, memo) + dp(step - 2, memo) # ways to (n-1) + (n-2) + return memo[step] + + return dp(n, memo) + From 64aa6d94786b4c8b7c016a9e168a9ec620b40e64 Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Wed, 18 Dec 2024 12:06:04 +0900 Subject: [PATCH 4/8] fix solution: logic error fix --- climbing-stairs/dusunax.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/climbing-stairs/dusunax.py b/climbing-stairs/dusunax.py index ea378a3a1..c6501c180 100644 --- a/climbing-stairs/dusunax.py +++ b/climbing-stairs/dusunax.py @@ -45,7 +45,7 @@ def climbStairsLoop(self, n: int) -> int: # SC: O(1) prev2 = 1 # ways to step 0 - prev1 = 1 # ways to step 1 + prev1 = 2 # ways to step 1 for i in range(3, n + 1): # TC: O(n) current = prev1 + prev2 # ways to (n-1) + (n-2) From dbb43fc6c443297ee69aa177707eabc8acc0ac9d Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:50:28 +0900 Subject: [PATCH 5/8] add solution: 3sum --- 3sum/dusunax.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 3sum/dusunax.py diff --git a/3sum/dusunax.py b/3sum/dusunax.py new file mode 100644 index 000000000..e277b41e5 --- /dev/null +++ b/3sum/dusunax.py @@ -0,0 +1,50 @@ +''' +# Leetcode 15. 3Sum + +use **two pointers** to solve this problem. + +## Time and Space Complexity + +``` +TC: O(n^2) +SC: O(1) +``` + +### TC is O(n^2): +- sorting the list = O(n log n) +- iterating through the list and using two pointers to find the sum of three numbers. = O(n^2) + +### SC is O(1): +- sorting in place = O(1) +''' + +class Solution: + def threeSum(self, nums: List[int]) -> List[List[int]]: + nums.sort() # TC: O(n log n), SC: O(1) + result = [] # result are part of the output => do not count toward auxiliary (extra) space. + + for i in range(len(nums)): # TC: O(n^2) + if i > 0 and nums[i] == nums[i - 1]: + continue + + j = i + 1 + k = len(nums) - 1 + while j < k: + currSum = nums[i] + nums[j] + nums[k] + + if currSum < 0: + j += 1 + elif currSum > 0: + k -= 1 + else: + result.append([nums[i], nums[j], nums[k]]) + + while j < k and nums[j] == nums[j + 1]: + j += 1 + while j < k and nums[k] == nums[k - 1]: + k -= 1 + + j += 1 + k -= 1 + + return result From 838bd0fba29e620f3dff37cec7687b4e37ae4b47 Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Sat, 21 Dec 2024 03:22:02 +0900 Subject: [PATCH 6/8] add solution: construct-binary-tree-from-preorder-and-inorder-traversal --- .../dusunax.py | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py b/construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py new file mode 100644 index 000000000..d8f8df5eb --- /dev/null +++ b/construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py @@ -0,0 +1,95 @@ +# 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: + ''' + A. ์žฌ๊ท€ ํ’€์ด + preorder์™€ inorder์˜ ๊ฐ๊ฐ์˜ ๋ฒ”์œ„๋ฅผ ์กฐ์ •ํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑ + ''' + def buildTreeA(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + def setTree(pre_left, pre_right, in_left, in_right): + # ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: preorder ๋ฒ”์œ„๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ + if pre_left > pre_right: + return None + + val = preorder[pre_left] # preorder์˜ ํ˜„์žฌ ๋ฃจํŠธ ๋…ธ๋“œ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ + mid = TreeNode(val) # ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ์ƒ์„ฑ + + mid_inorder = inorder_idx_map[val] # ๋ฃจํŠธ ๋…ธ๋“œ์˜ inorder ์ธ๋ฑ์Šค ๊ฐ€์ ธ์˜ค๊ธฐ + left_size = mid_inorder - in_left # ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํฌ๊ธฐ ๊ณ„์‚ฐ + + # ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ƒ์„ฑ: preorder์™€ inorder์˜ ๋ฒ”์œ„๋ฅผ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ์กฐ์ • + mid.left = setTree( + pre_left + 1, pre_left + left_size, in_left, mid_inorder - 1 + ) + + # ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ƒ์„ฑ: preorder์™€ inorder์˜ ๋ฒ”์œ„๋ฅผ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ์กฐ์ • + mid.right = setTree( + pre_left + left_size + 1, pre_right, mid_inorder + 1, in_right + ) + + return mid # ํ˜„์žฌ ๋…ธ๋“œ ๋ฐ˜ํ™˜ + + # inorder๋ฅผ ๊ฐ’ -> ์ธ๋ฑ์Šค ๋งตํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ (O(n)) + inorder_idx_map = {value: idx for idx, value in enumerate(inorder)} + + # ํŠธ๋ฆฌ ์ƒ์„ฑ ์‹œ์ž‘ (preorder์™€ inorder ์ „์ฒด ๋ฒ”์œ„ ์‚ฌ์šฉ) + return setTree(0, len(preorder) - 1, 0, len(inorder) - 1) + + + ''' + # B. ์žฌ๊ท€ ํ’€์ด + ๊ณต๊ฐ„ ์ตœ์ ํ™” + # ๋ ˆํผ๋Ÿฐ์Šค ๋งํฌ์˜ ํ’€์ด 2: https://www.algodale.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + # ํŠน์ง•: ์ˆœํšŒ ์‹œ๋งˆ๋‹ค ์ธ๋ฑ์Šค๋ฅผ ์ฐพ๋Š” ๊ณผ์ •์ด ์žˆ์Œ + ''' + def buildTreeB(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + # pre: ํ˜„์žฌ preorder์—์„œ ํ™•์ธํ•  ์ธ๋ฑ์Šค + # start, end: inorder์—์„œ ์‚ฌ์šฉํ•  ์‹œ์ž‘/์ข…๋ฃŒ ๋ฒ”์œ„ + def setTree(pre, start, end): + # ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: ๋ฒ”์œ„๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ํŠธ๋ฆฌ๋ฅผ ๋” ์ด์ƒ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ + if not (pre < len(preorder) and start <= end): # preorder์—์„œ ํ™•์ธํ•  ์ธ๋ฑ์Šค๊ฐ€ ๋ฒ”์œ„์—์„œ ๋‚˜๊ฐ, ํˆฌ ํฌ์ธํ„ฐ๊ฐ€ ๋งŒ๋‚จ + return None + + val = preorder[pre] # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’ + root = inorder.index(val) # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ - SC: O(n) + + left = setTree(pre + 1, start, root - 1) + # inorder์—์„œ root๋…ธ๋“œ์˜ ์™ผ์ชฝ์€ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ + # pre์˜ ๋ณ€ํ™”: ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด +1 ์ด๋™ + + right = setTree(pre + 1 + root - start, root + 1, end) + # inorder์—์„œ root๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ์€ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ + # pre์˜ ๋ณ€ํ™”: ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด +1 ์ด๋™ + (root - start) ๐Ÿ‘ˆ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํฌ๊ธฐ ๋งŒํผ ๋” ์ด๋™ + + return TreeNode(preorder[pre], left, right) # ํŠธ๋ฆฌ ๋…ธ๋“œ ์ƒ์„ฑ + + # preorder ์ตœ์ดˆ ์ธ๋ฑ์Šค = ๋ฃจํŠธ ๋…ธ๋“œ(0), inorder์˜ ์ฒ˜์Œ(0)๊ณผ ๋(len(inorder) - 1) ์ธ๋ฑ์Šค + return setTree(0, 0, len(inorder) - 1) + + ''' + C. ์žฌ๊ท€ ํ’€์ด + ์‹œ๊ฐ„ ์ตœ์ ํ™” + ๋ ˆํผ๋Ÿฐ์Šค ๋งํฌ์˜ ํ’€์ด 3: https://www.algodale.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + ํŠน์ง•: A์—์„œ preorder๋ฅผ ์ฐพ๋Š” O(n) ๊ณผ์ •์„ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜์—ฌ O(1)๋กœ ์ตœ์ ํ™” + ''' + def buildTreeC(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + # enumerate: ์ธ๋ฑ์Šค์™€ ๊ฐ’์„ ๋™์‹œ์— ๋ฐ˜ํ™˜ + # inorder๋ฅผ val -> idx๋กœ ๋งคํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ + inorder_index_map = {val: idx for idx, val in enumerate(inorder)} + # preorder๋ฅผ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•œ iterator ๊ฐ์ฒด ์ƒ์„ฑ + pre_iter = iter(preorder) + + def setTree(start, end): + if start > end: # ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: ๋ฒ”์œ„๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ํŠธ๋ฆฌ๋ฅผ ๋” ์ด์ƒ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ + return None + + root_val = next(pre_iter) # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’, ๋งค ์ˆœํšŒ๋งˆ๋‹ค ๋‹ค์Œ preorder ๋…ธ๋“œ(root)์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ด + root = inorder_index_map[root_val] # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค๋ฅผ O(1) ์‹œ๊ฐ„์œผ๋กœ ์ฐพ๊ธฐ + + left = setTree(start, root - 1) # ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ + right = setTree(root + 1, end) # ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ + return TreeNode(root_val, left, right) # ํŠธ๋ฆฌ ๋…ธ๋“œ ์ƒ์„ฑ + + return setTree(0, len(inorder) - 1) # inorder์˜ ์ฒ˜์Œ(0)๊ณผ ๋(len(inorder) - 1) ์ธ๋ฑ์Šค From c7d7f8406fdaec040f8e9ca370a717f9f0b9ce1e Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Sat, 21 Dec 2024 03:30:30 +0900 Subject: [PATCH 7/8] =?UTF-8?q?update=20solution:=20construct-binary-tree-?= =?UTF-8?q?from-preorder-and-inorder-traversal=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dusunax.py | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py b/construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py index d8f8df5eb..5d3571e0c 100644 --- a/construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py +++ b/construct-binary-tree-from-preorder-and-inorder-traversal/dusunax.py @@ -1,9 +1,33 @@ -# 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 + +''' +# Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal + +use **recursive** to solve this problem. + +## Time and Space Complexity + +### A. recursive & change range of preorder and inorder + +``` +TC: O(n) +SC: O(n) +``` + +### B. recursive & search index (of inorder) + +``` +TC: O(n^2) +SC: O(n) +``` + +### C. recursive & hash table + +``` +TC: O(n) +SC: O(n) +``` + +''' class Solution: ''' A. ์žฌ๊ท€ ํ’€์ด @@ -33,10 +57,10 @@ def setTree(pre_left, pre_right, in_left, in_right): return mid # ํ˜„์žฌ ๋…ธ๋“œ ๋ฐ˜ํ™˜ - # inorder๋ฅผ ๊ฐ’ -> ์ธ๋ฑ์Šค ๋งตํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ (O(n)) + # inorder๋ฅผ ๊ฐ’ -> ์ธ๋ฑ์Šค ๋งตํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ - TC: O(n), SC: O(n) inorder_idx_map = {value: idx for idx, value in enumerate(inorder)} - # ํŠธ๋ฆฌ ์ƒ์„ฑ ์‹œ์ž‘ (preorder์™€ inorder ์ „์ฒด ๋ฒ”์œ„ ์‚ฌ์šฉ) + # ํŠธ๋ฆฌ ์ƒ์„ฑ ์‹œ์ž‘ (preorder์™€ inorder ์ „์ฒด ๋ฒ”์œ„ ์‚ฌ์šฉ) - TC: O(n), SC: O(n) return setTree(0, len(preorder) - 1, 0, len(inorder) - 1) @@ -54,7 +78,7 @@ def setTree(pre, start, end): return None val = preorder[pre] # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’ - root = inorder.index(val) # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ - SC: O(n) + root = inorder.index(val) # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ - TC: O(n) left = setTree(pre + 1, start, root - 1) # inorder์—์„œ root๋…ธ๋“œ์˜ ์™ผ์ชฝ์€ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ @@ -67,7 +91,7 @@ def setTree(pre, start, end): return TreeNode(preorder[pre], left, right) # ํŠธ๋ฆฌ ๋…ธ๋“œ ์ƒ์„ฑ # preorder ์ตœ์ดˆ ์ธ๋ฑ์Šค = ๋ฃจํŠธ ๋…ธ๋“œ(0), inorder์˜ ์ฒ˜์Œ(0)๊ณผ ๋(len(inorder) - 1) ์ธ๋ฑ์Šค - return setTree(0, 0, len(inorder) - 1) + return setTree(0, 0, len(inorder) - 1) # TC: O(n^2), SC: O(n) ''' C. ์žฌ๊ท€ ํ’€์ด + ์‹œ๊ฐ„ ์ตœ์ ํ™” From b506385bc6c45d3f835ab15fa9c2800fcd3a460c Mon Sep 17 00:00:00 2001 From: Dusuna <94776135+dusunax@users.noreply.github.com> Date: Sat, 21 Dec 2024 17:35:09 +0900 Subject: [PATCH 8/8] add solution: decode-ways --- decode-ways/dusunax.py | 56 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 decode-ways/dusunax.py diff --git a/decode-ways/dusunax.py b/decode-ways/dusunax.py new file mode 100644 index 000000000..dda61ca05 --- /dev/null +++ b/decode-ways/dusunax.py @@ -0,0 +1,56 @@ +''' +# Leetcode 91. Decode Ways + +use **dynamic programming** to solve this problem. + +## Time and Space Complexity + +``` +TC: O(n) +SC: O(n) +``` + +### TC is O(n): +- iterating through the string and checking if the current character is decodable. = O(n) + +### SC is O(n): +- creating a dp array of size n + 1 = O(n) +''' +class Solution: + def isDecodable(self, str: str): + return 1 <= int(str) <= 26 and str[0] != '0' + + def numDecodings(self, s: str) -> int: + if s[0] == "0": + return 0 + + n = len(s) + dp = (n + 1) * [0] + dp[0] = 1 + dp[1] = 1 + + for i in range(2, n + 1): + one = s[i - 1] + two = s[i - 2:i] + + if self.isDecodable(one): + dp[i] += dp[i - 1] + if self.isDecodable(two): + dp[i] += dp[i - 2] + + return dp[n] + +''' +# sudo code +- ํ—ฌํผํ•จ์ˆ˜: 0์œผ๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ , 1~26์ธ ๊ฒฝ์šฐ True +- numDecodingsํ•จ์ˆ˜ + 1. n: ๋ฌธ์ž์—ด s์˜ ๊ธธ์ด + 2. dp: ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•  ๋ฐฐ์—ด, n+1 + 3. BaseCase: dp[0] = 1, dp[1] = 1 + 4. for loop 2 to n: + one = s์˜ i-1 ์œ„์น˜์˜ 1๊ธ€์ž (ํ˜„์žฌ ๊ธ€์ž) + two = s์˜ i-2๋ถ€ํ„ฐ i๊นŒ์ง€ ์ž๋ฅธ 2๊ธ€์ž (ํ˜„์žฌ ๊ธ€์ž ํฌํ•จ ์ด์ „ ๊ธ€์ž) + if one is decodable => dp[i] += dp[i - 1] i๊ธธ์ด์ผ ๋•Œ, dp์˜ -1 ๊ฒฝ์šฐ์˜ ๋งŒํผ์ˆ˜ ์ถ”๊ฐ€ (ํ˜„์žฌ ๊ธ€์ž๋ฅผ ํ•œ ๊ธ€์ž๋กœ ํ•ด์„) + if two is decodable => dp[i] += dp[i - 2] i๊ธธ์ด์ผ ๋•Œ, dp์˜ -2 ๊ฒฝ์šฐ์˜ ์ˆ˜ ๋งŒํผ ์ถ”๊ฐ€ (ํ˜„์žฌ ๊ธ€์ž๋ฅผ ๋‘ ๊ธ€์ž๋กœ ํ•ด์„) + 5. dp[n] ๋ฐ˜ํ™˜: ์ตœ์ข… ๋””์ฝ”๋“œ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜ ๊ฒฐ๊ณผ +'''