diff --git a/container-with-most-water/pmjuu.py b/container-with-most-water/pmjuu.py new file mode 100644 index 000000000..d88751ab4 --- /dev/null +++ b/container-with-most-water/pmjuu.py @@ -0,0 +1,26 @@ +''' +시간 복잡도: O(n) +- 두 포인터를 이동하면서 배열을 한 번만 순회하므로 시간 복잡도는 O(n)입니다. + +공간 복잡도: O(1) +- 추가 메모리를 사용하지 않고 변수만 사용하므로 O(1)입니다. +''' + +from typing import List + + +class Solution: + def maxArea(self, height: List[int]) -> int: + max_area = 0 + left, right = 0, len(height) - 1 + + while left < right: + current_area = (right - left) * min(height[left], height[right]) + max_area = max(current_area, max_area) + + if height[left] < height[right]: + left += 1 + else: + right -= 1 + + return max_area diff --git a/design-add-and-search-words-data-structure/pmjuu.py b/design-add-and-search-words-data-structure/pmjuu.py new file mode 100644 index 000000000..8d9f711df --- /dev/null +++ b/design-add-and-search-words-data-structure/pmjuu.py @@ -0,0 +1,58 @@ +''' +* L: 단어의 길이 +시간복잡도: O(1) +- addWord(word): O(L), 최대 단어 길이가 25로 제한되므로 이 작업은 상수 시간에 가깝습니다. +- search(word): O(L * 26^d), 여기서 26은 알파벳 소문자의 개수를 의미합니다. d는 단어 내 '.'의 개수인데, 2로 제한되므로 상수 시간에 가깝습니다. +공간복잡도: +- Trie 구조에 저장되는 문자의 수에 비례합니다. 단어의 총 길이를 T라고 하면 공간복잡도는 O(T) 입니다. +''' + + +class Trie: + def __init__(self): + self.children = {} + self.is_end_of_word = False + +class WordDictionary: + + def __init__(self): + # Trie의 루트 노드 초기화 + self.root = Trie() + + def addWord(self, word: str) -> None: + current = self.root + + for char in word: + if char not in current.children: + current.children[char] = Trie() + + current = current.children[char] + + current.is_end_of_word = True + + def search(self, word: str) -> bool: + def dfs(node, i): + if i == len(word): + return node.is_end_of_word + + char = word[i] + if char == '.': + # '.'인 경우 모든 자식 노드에 대해 탐색 + for child in node.children.values(): + if dfs(child, i + 1): + return True + return False + + if char not in node.children: + return False + + return dfs(node.children[char], i + 1) + + return dfs(self.root, 0) + + + +# Your WordDictionary object will be instantiated and called as such: +# obj = WordDictionary() +# obj.addWord(word) +# param_2 = obj.search(word) diff --git a/longest-increasing-subsequence/pmjuu.py b/longest-increasing-subsequence/pmjuu.py new file mode 100644 index 000000000..575e06bec --- /dev/null +++ b/longest-increasing-subsequence/pmjuu.py @@ -0,0 +1,40 @@ +''' +Dynamic programming 활용 + +시간복잡도: O(n^2) - 두 개의 중첩된 반복문이 nums 배열을 탐색함 +공간복잡도: O(n) - dp 배열에 숫자 개수(n)만큼 공간이 필요함 +''' + +def lengthOfLIS_n2(nums): + n = len(nums) + dp = [1] * n + + for i in range(1, n): + for j in range(i): + if nums[j] < nums[i]: + dp[i] = max(dp[i], dp[j] + 1) # 이전 LIS 길이에 1 추가 + + return max(dp) # dp 배열의 최대값이 최장 길이 + + +''' +이진탐색 활용 + +시간복잡도: O(n log n) - 각 숫자에 대해 이진 탐색(bisect_left)을 수행함 +공간복잡도: O(n) - sub 리스트에 최대 n개의 숫자가 저장될 수 있음 +''' + +from bisect import bisect_left + +def lengthOfLIS_nlogn(nums): + sub = [] # 현재까지 찾은 LIS의 숫자들을 저장 + + for num in nums: + pos = bisect_left(sub, num) # 삽입 위치를 이진 탐색으로 찾음 + + if pos == len(sub): + sub.append(num) # 삽입 위치가 sub의 범위 밖이면 숫자 추가 + else: + sub[pos] = num # 삽입 위치가 범위 안이면 해당 위치의 숫자를 현재 숫자로 교체 + + return len(sub) diff --git a/spiral-matrix/pmjuu.py b/spiral-matrix/pmjuu.py new file mode 100644 index 000000000..d7ac14a59 --- /dev/null +++ b/spiral-matrix/pmjuu.py @@ -0,0 +1,33 @@ +''' +시간복잡도: O(m * n) - 모든 행렬의 요소를 한 번씩 방문 +공간복잡도: O(1) - 추가 공간 없이 결과를 저장 +''' +from typing import List + + +class Solution: + def spiralOrder(self, matrix: List[List[int]]) -> List[int]: + result = [] + top, bottom = 0, len(matrix) - 1 + left, right = 0, len(matrix[0]) - 1 + + while top <= bottom and left <= right: + for col in range(left, right + 1): + result.append(matrix[top][col]) + top += 1 + + for row in range(top, bottom + 1): + result.append(matrix[row][right]) + right -= 1 + + if top <= bottom: + for col in range(right, left - 1, -1): + result.append(matrix[bottom][col]) + bottom -= 1 + + if left <= right: + for row in range(bottom, top - 1, -1): + result.append(matrix[row][left]) + left += 1 + + return result diff --git a/valid-parentheses/pmjuu.py b/valid-parentheses/pmjuu.py new file mode 100644 index 000000000..21256a2f3 --- /dev/null +++ b/valid-parentheses/pmjuu.py @@ -0,0 +1,23 @@ +''' +시간 복잡도: O(n) +- 문자열 s의 길이를 n이라고 할 때, 문자열의 각 문자를 한 번씩 순회하며 처리하므로 O(n)입니다. + +공간 복잡도: O(n) +- 스택에 열린 괄호를 저장하는 데 사용되는 공간이 최악의 경우 문자열 s의 길이 n과 같을 수 있으므로 O(n)입니다. +''' + +class Solution: + def isValid(self, s: str) -> bool: + stack = [] + bracket_map = {")": "(", "}": "{", "]": "["} + + for bracket in s: + if bracket in bracket_map: + if stack and stack[-1] == bracket_map[bracket]: + stack.pop() + else: + return False + else: + stack.append(bracket) + + return len(stack) == 0