diff --git a/coin-change/parkhojeong.py b/coin-change/parkhojeong.py new file mode 100644 index 0000000000..45bd947a31 --- /dev/null +++ b/coin-change/parkhojeong.py @@ -0,0 +1,21 @@ +class Solution: + def coinChange(self, coins: List[int], amount: int) -> int: + if amount == 0: + return 0 + + dp = [1 if x in coins else 0 for x in range(amount + 1)] + MAX_VALUE = sys.maxsize + + for i in range(1, amount + 1): + if dp[i] != 0: + continue + + dp[i] = MAX_VALUE + for coin in coins: + if i - coin > 0 and dp[i - coin] > 0: + dp[i] = min(dp[i - coin] + 1, dp[i]) + + if dp[amount] == MAX_VALUE: + return -1 + + return dp[amount] diff --git a/find-minimum-in-rotated-sorted-array/parkhojeong.py b/find-minimum-in-rotated-sorted-array/parkhojeong.py new file mode 100644 index 0000000000..e7fdd2f29c --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/parkhojeong.py @@ -0,0 +1,15 @@ +class Solution: + def findMin(self, nums: List[int]) -> int: + lo, hi = 0, len(nums) - 1 + while lo < hi: + mid = (lo + hi) // 2 + + if nums[lo] < nums[hi]: + return nums[lo] + + if nums[mid] < nums[hi]: + hi = mid + else: + lo = mid + 1 + + return nums[lo] diff --git a/maximum-depth-of-binary-tree/parkhojeong.py b/maximum-depth-of-binary-tree/parkhojeong.py new file mode 100644 index 0000000000..8658248d4c --- /dev/null +++ b/maximum-depth-of-binary-tree/parkhojeong.py @@ -0,0 +1,15 @@ +# 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 maxDepth(self, root: Optional[TreeNode]) -> int: + return self.dfs(root, 0) + + def dfs(self, root, depth) -> int: + if not root: + return depth + + return max(self.dfs(root.left, depth + 1), self.dfs(root.right, depth + 1)) diff --git a/merge-two-sorted-lists/parkhojeong.py b/merge-two-sorted-lists/parkhojeong.py new file mode 100644 index 0000000000..8f6cefd9e3 --- /dev/null +++ b/merge-two-sorted-lists/parkhojeong.py @@ -0,0 +1,25 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: + dummy_head = ListNode() + cur = dummy_head + + while list1 and list2: + if list1.val <= list2.val: + cur.next = list1 + list1 = list1.next + else: + cur.next = list2 + list2 = list2.next + cur = cur.next + + if list1: + cur.next = list1 + elif list2: + cur.next = list2 + + return dummy_head.next diff --git a/word-search/parkhojeong.py b/word-search/parkhojeong.py new file mode 100644 index 0000000000..50d7286826 --- /dev/null +++ b/word-search/parkhojeong.py @@ -0,0 +1,51 @@ +from collections import Counter +from typing import List + +class Solution: + def exist(self, board: List[List[str]], word: str) -> bool: + row_len, col_len = len(board), len(board[0]) + + board_freq = Counter(ch for row in board for ch in row) + + for ch, need in Counter(ch for ch in word).items(): + if board_freq.get(ch, 0) < need: + return False + + if board_freq.get(word[0], 0) > board_freq.get(word[-1], 0): + word = word[::-1] + + DIRECTIONS = ((-1, 0), (1, 0), (0, -1), (0, 1)) + MARKER = "" + + def in_bounds(r: int, c: int) -> bool: + return 0 <= r < row_len and 0 <= c < col_len + + def backtrack(r: int, c: int, idx: int) -> bool: + if idx == len(word) - 1: + return True + + saved_char = board[r][c] + board[r][c] = MARKER + board_freq[saved_char] -= 1 + + for dr, dc in DIRECTIONS: + nr, nc = r + dr, c + dc + next_ch = word[idx + 1] + + if (in_bounds(nr, nc) + and board[nr][nc] != MARKER + and board[nr][nc] == next_ch + and board_freq[next_ch] > 0 + and backtrack(nr, nc, idx + 1)): + return True + + board[r][c] = saved_char + board_freq[saved_char] += 1 + return False + + for r in range(row_len): + for c in range(col_len): + if board[r][c] == word[0] and backtrack(r, c, 0): + return True + + return False