diff --git a/binary-tree-level-order-traversal/yyyyyyyyyKim.py b/binary-tree-level-order-traversal/yyyyyyyyyKim.py new file mode 100644 index 000000000..82fac2170 --- /dev/null +++ b/binary-tree-level-order-traversal/yyyyyyyyyKim.py @@ -0,0 +1,40 @@ +# 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 + +from collections import deque + +class Solution: + def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + + # BFS(큐 사용) + # 시간복잡도 O(n), 공간복잡도 O(n) + + if not root: + return [] + + # 큐에 root노드 추가(초기화) + q = deque([root]) + answer = [] + + # 큐가 빌 때까지 탐색(모든 노드 탐색) + while q: + level = [] # 현재 레벨의 노드 저장할 리스트 + + for _ in range(len(q)): # 현재 레벨에 있는 노드 수만큼 반복 + node = q.popleft() # 큐에서 노드 꺼내서 + level.append(node.val) # level에 저장 + + # 자식 노드들이 있다면 큐에 추가 + if node.left: + q.append(node.left) + if node.right: + q.append(node.right) + + # 현재 레벨 answer에 추가 + answer.append(level) + + return answer diff --git a/counting-bits/yyyyyyyyyKim.py b/counting-bits/yyyyyyyyyKim.py new file mode 100644 index 000000000..cda94a102 --- /dev/null +++ b/counting-bits/yyyyyyyyyKim.py @@ -0,0 +1,12 @@ +class Solution: + def countBits(self, n: int) -> List[int]: + # 시간복잡도 O(n), 공간복잡도 O(n) + + # 0으로 초기화 + answer = [0]*(n+1) + + for i in range(1,n+1): + # i//2(마지막비트를제외한부분)의 1의 개수 + i의 마지막비트(홀수면 1, 짝수면 0) + answer[i] = answer[i//2] + (i&1) + + return answer diff --git a/house-robber-ii/yyyyyyyyyKim.py b/house-robber-ii/yyyyyyyyyKim.py new file mode 100644 index 000000000..d593815c6 --- /dev/null +++ b/house-robber-ii/yyyyyyyyyKim.py @@ -0,0 +1,25 @@ +class Solution: + def rob(self, nums: List[int]) -> int: + + # DP + # 시간복잡도 O(n^2), 공간복잡도 O(n) + + # 집이 1개~3개인 경우, 가장 큰 집만 털기 + if len(nums) <= 3: + return max(nums) + + # 첫 번째 집을 포함하지 않고 털기 + dp1 = [0]*len(nums) + dp1[1] = nums[1] + dp1[2] = nums[2] + for i in range(2, len(nums)): + dp1[i] = max(dp1[i-1], max(dp1[:i-1])+nums[i]) + + # 마지막 집을 포함하지 않고 털기 + dp2 = [0]*len(nums) + dp2[0] = nums[0] + dp2[1] = nums[1] + for i in range(2, len(nums)-1): + dp2[i] = max(dp2[i-1], max(dp2[:i-1])+nums[i]) + + return max(max(dp1), max(dp2)) diff --git a/meeting-rooms-ii/yyyyyyyyyKim.py b/meeting-rooms-ii/yyyyyyyyyKim.py new file mode 100644 index 000000000..15bf2d94b --- /dev/null +++ b/meeting-rooms-ii/yyyyyyyyyKim.py @@ -0,0 +1,48 @@ +from typing import ( + List, +) +from lintcode import ( + Interval, +) + +""" +Definition of Interval: +class Interval(object): + def __init__(self, start, end): + self.start = start + self.end = end +""" + +class Solution: + """ + @param intervals: an array of meeting time intervals + @return: the minimum number of conference rooms required + """ + def min_meeting_rooms(self, intervals: List[Interval]) -> int: + + # 투포인터 + # 시간복잡도 O(n log n) , 공간복잡도 O(n) + + # 시작 시간과 종료 시간을 각각 정렬 + s = sorted([i.start for i in intervals]) + e = sorted([i.end for i in intervals]) + + s_pointer = e_pointer = 0 + rooms = max_rooms = 0 + + while s_pointer < len(intervals): + + # 기존 회의가 끝나기 전에 새로운 회의 시작(새로운 방 필요) + if s[s_pointer] < e[e_pointer]: + rooms += 1 + s_pointer += 1 + # 기존 회의 종료(방 퇴실) + else: + rooms -= 1 + e_pointer += 1 + + # 지금까지 필요한 방의 최대값을 갱신 + max_rooms = max(max_rooms, rooms) + + return max_rooms + diff --git a/word-search-ii/yyyyyyyyyKim.py b/word-search-ii/yyyyyyyyyKim.py new file mode 100644 index 000000000..438051b03 --- /dev/null +++ b/word-search-ii/yyyyyyyyyKim.py @@ -0,0 +1,65 @@ +class TrieNode: + def __init__(self): + self.children = {} # 현재 문자에서 갈 수 있는 다음 문자들 저장 + self.word = None # 이노드에서 끝나는 단어가 있다면 저장 + +class Solution: + def findWords(self, board: List[List[str]], words: List[str]) -> List[str]: + + # 다시풀어볼것. 어려웠음. Trie! 보드로 탐색해야함!(단어로 탐색하는게 아님!) + # DFS(백트래킹), trie + # DFS로만 풀면 TLE(시간초과)뜸. trie구조를 이용해야함. + + # Trie루트노드 생성 + root = TrieNode() + + # words 리스트를 기반으로 Trie 생성 + for word in words: + node = root + + for i in word: + + if i not in node.children: + node.children[i] = TrieNode() + node = node.children[i] + + node.word = word # 단어 끝에서 word 저장 + + answer = [] + + rows, cols = len(board), len(board[0]) + + # DFS + def dfs(x, y, node): + c = board[x][y] + + # 현재 문자가 트라이에 없으면 바로 종료 + if c not in node.children: + return + + next_node = node.children[c] + + # 단어를 찾으면 answer에 추가하고, 중복방지위해 None처리 + if next_node.word: + answer.append(next_node.word) + next_node.word = None # 중복방지 + + board[x][y] = '#' # 현재위치 '#'로 방문표시 + + # 상하좌우 DFS 탐색 + for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]: + nx, ny = x + dx, y + dy + # 범위 내에 있고, 아직 방문하지 않은 위치라면 DFS 탐색 + if 0 <= nx < rows and 0 <= ny < cols and board[nx][ny] != '#': + dfs(nx, ny, next_node) + + # DFS 종료 후, 원래 문자로 복구(백트래킹) + board[x][y] = c # 원상복구 + + + # DFS 시작점(모든 보드 칸을 시작점으로 DFS 탐색) + for i in range(rows): + for j in range(cols): + dfs(i, j, root) + + return answer