diff --git a/coin-change/ppxyn1.py b/coin-change/ppxyn1.py new file mode 100644 index 0000000000..833adb130e --- /dev/null +++ b/coin-change/ppxyn1.py @@ -0,0 +1,47 @@ +# idea: DFS/BFS, DP + +from collections import deque +class Solution: + def coinChange(self, coins: List[int], amount: int) -> int: + # Why Greedy is not possiple way? + # A greedy is only optimal in specific coin systems (e.g., denominations like 1, 5, 10, 25) + # For arbitrary coin denominations, a greedy approach does not always yield the optimal solution. + queue = deque([(0,0)]) # (동전갯수, 누적금액) + while queue: + count, total = queue.popleft() + if total == amount: + return count + for coin in coins: + if total + coin <= amount: + queue.append([count+1, total+ coin]) + return -1 + + # # BFS + # def coinChange(self, coins: List[int], amount: int) -> int: + # queue = deque([(0,0)]) # (동전갯수, 누적금액) + # visited = set() + # while queue: + # count, total = queue.popleft() + # if total == amount: + # return count + # if total in visited: + # continue + # visited.add(total) + # for coin in coins: + # if total + coin <= amount: + # queue.append([count+1, total+ coin]) + # return -1 + + + # DP + # dp[i] = min(dp[i], dp[i-coin]+1) + # from collections import deque + # class Solution: + # def coinChange(self, coins: List[int], amount: int) -> int: + # dp=[0]+[amount+1]*amount + # for coin in coins: + # for i in range(coin, amount+1): + # dp[i] = min(dp[i], dp[i-coin]+1) + # return dp[amount] if dp[amount] < amount else -1 + + diff --git a/find-minimum-in-rotated-sorted-array/ppxyn1.py b/find-minimum-in-rotated-sorted-array/ppxyn1.py new file mode 100644 index 0000000000..804638c185 --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/ppxyn1.py @@ -0,0 +1,19 @@ +class Solution: + def findMin(self, nums: List[int]) -> int: + # You must write an algorithm that runs in O(log n) time. >> Binary Search + # It's possible because the array is sorted. + left, right = 0, len(nums)-1 + + while left < right: + mid = (left + right) // 2 + # If the value at mid is greater than the value at the right end, it means the minimum place to the right of mid. + if nums[mid] > nums[right]: + left = mid + 1 + else: + # mid can be minimum number + # But is it possible to solve it with "right=mid-1"? e.g,[4,5,6,7,0,1,2] + right = mid + return nums[left] + + + diff --git a/maximum-depth-of-binary-tree/ppxyn1.py b/maximum-depth-of-binary-tree/ppxyn1.py new file mode 100644 index 0000000000..7b5a42c2ec --- /dev/null +++ b/maximum-depth-of-binary-tree/ppxyn1.py @@ -0,0 +1,36 @@ +# idea : DFS + +# time : O(n) +# space : O(n) + +class Solution: + def maxDepth(self, root: Optional[TreeNode]) -> int: + # edge case + if not root: + return 0 + max_depth = 0 + stack = [(root, 1)] + while stack: + node, depth = stack.pop() + max_depth = max(depth, max_depth) + if node.left: + stack.append((node.left, depth+1)) + if node.right: + stack.append((node.right, depth+1)) + return max_depth + + + + +# another way : Down-top : recursive +# class Solution: +# def maxDepth(self, root: Optional[TreeNode]) -> int: +# if not root: +# return 0 +# return 1 + max( +# self.maxDepth(root.left), +# self.maxDepth(root.right) +# ) + + + diff --git a/merge-two-sorted-lists/ppxyn1.py b/merge-two-sorted-lists/ppxyn1.py new file mode 100644 index 0000000000..9c153c2ce2 --- /dev/null +++ b/merge-two-sorted-lists/ppxyn1.py @@ -0,0 +1,31 @@ +# idea : Two Pointer +# It was first time solving a two-pointer problem using nodes instead of arrays, and I realized I'm still not very familiar with nodes yet. +class Solution: + def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: + dummy = ListNode(None) + node = dummy + while list1 and list2: + if list1.val < list2.val: + node.next = list1 + list1 = list1.next + else: + node.next = list2 + list2 = list2.next + node = node.next + node.next = list1 or list2 + return dummy.next + + +# Another way to solve it +# class Solution: +# def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: +# if not (list1 and list2): +# return list1 or list2 +# if list1.val < list2.val: +# list1.next = self.mergeTwoLists(list1.next, list2) +# return list1 +# else: +# list2.next = self.mergeTwoLists(list1, list2.next) +# return list2 + + diff --git a/word-search/ppxyn1.py b/word-search/ppxyn1.py new file mode 100644 index 0000000000..c273792650 --- /dev/null +++ b/word-search/ppxyn1.py @@ -0,0 +1,37 @@ +# idea : dfs +class Solution: + def exist(self, board: List[List[str]], word: str) -> bool: + ROWS, COLS = len(board), len(board[0]) + visited = [[False]*COLS for _ in range(ROWS)] + + def dfs(r, c, index): + if r < 0 or r >= ROWS or c < 0 or c >= COLS: + return False + if visited[r][c] or board[r][c] != word[index]: + return False + + if index == len(word) - 1: + return True + + visited[r][c] = True + + found = (dfs(r+1, c, index+1) or + dfs(r-1, c, index+1) or + dfs(r, c+1, index+1) or + dfs(r, c-1, index+1)) + + # For next backtracking + visited[r][c] = False + + return found + + # Run DFS from every cell as a starting point + for row in range(ROWS): + for col in range(COLS): + if dfs(row, col, 0): + return True + + return False + + +