diff --git a/course-schedule/yyyyyyyyyKim.py b/course-schedule/yyyyyyyyyKim.py new file mode 100644 index 000000000..4ee0931cf --- /dev/null +++ b/course-schedule/yyyyyyyyyKim.py @@ -0,0 +1,44 @@ +class Solution: + def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: + + # 재귀 DFS + # 그래프 만들기 + # graph[i] = [j, ...] : i를 듣기 위해 선행해야 하는 과목j들 저장 + graph = [[] for _ in range(numCourses)] + for i, j in prerequisites: + graph[i].append(j) + + # visited + # 0: 방문 안함 + # 1: 방문 중(현재 탐색 중) + # 2: 방문 완료(사이클 없음 확인 완료) + visited = [0]*numCourses + + def dfs(course): + # 방문 중인데 또 방문 = 사이클 존재 -> False + if visited[course] == 1: + return False + + # 이미 방문 완료(탐색 완료) + if visited[course] == 2: + return True + + # 방문 중 표시 + visited[course] = 1 + + # 선행과목들 DFS로 확인 + for i in graph[course]: + if not dfs(i): + return False + + # 탐색 완료(방문 완료) + visited[course] = 2 + + return True + + # 모든 과목 DFS 탐색 + for i in range(numCourses): + if not dfs(i): + return False + + return True diff --git a/invert-binary-tree/yyyyyyyyyKim.py b/invert-binary-tree/yyyyyyyyyKim.py new file mode 100644 index 000000000..3abbe6dbd --- /dev/null +++ b/invert-binary-tree/yyyyyyyyyKim.py @@ -0,0 +1,30 @@ +# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + + # 이진트리 뒤집기(좌우반전) + # DFS(stack이용, 시간복잡도 O(n), 공간복잡도 O(n)) + if not root: + return None + + stack = [root] + + while stack: + # 스택 맨뒤에 있는 거 pop해서 꺼내기 + node = stack.pop() + + # 자식 노드 교환 + node.left, node.right = node.right, node.left + + # 자식 노드를 스택에 추가 + if node.left: + stack.append(node.left) + if node.right: + stack.append(node.right) + + return root diff --git a/jump-game/yyyyyyyyyKim.py b/jump-game/yyyyyyyyyKim.py new file mode 100644 index 000000000..71d1a4b20 --- /dev/null +++ b/jump-game/yyyyyyyyyKim.py @@ -0,0 +1,32 @@ +class Solution: + def canJump(self, nums: List[int]) -> bool: + + # 그리디(시간복잡도 O(n), 공간복잡도 O(1)) + max_reach = 0 # 가장 멀리 갈 수 있는 위치 + + for i in range(len(nums)): + # max_reach가 i보다 작으면 nums[i]에 도달 불가 -> False + if i > max_reach: + return False + # 현재 위치i에서 점프했을 때 도달 가능한 최대 위치 업데이트 + max_reach = max(max_reach, i + nums[i]) + + # 도달 가능 + return True + + + # # 아래 방식(DP)은 시간초과뜸. + # # DP(시간복잡도 O(n^2), 공간복잡도 O(n)) + # # dp[i] = i번째에 도달 가능한지 여부 + # dp = [False]*len(nums) + # dp[0] = True # 시작점은 항상 도달 가능 + + # for i in range(1,len(nums)): + # for j in range(i): + # # j까지 갈 수 있고, j에서 i까지 점프 가능하면, True로 바꾸고 break(더 볼 필요없음) + # if dp[j] and j + nums[j] >= i: + # dp[i] = True + # break + + # # 마지막 인덱스 도달 여부 + # return dp[-1] diff --git a/merge-k-sorted-lists/yyyyyyyyyKim.py b/merge-k-sorted-lists/yyyyyyyyyKim.py new file mode 100644 index 000000000..353eec967 --- /dev/null +++ b/merge-k-sorted-lists/yyyyyyyyyKim.py @@ -0,0 +1,58 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + # 분할정복(divide and conquer), 쉽지않음,다시볼것,다른방식풀이들찾아볼것. + + # 빈 리스트일 경우 None 반환 + if len(lists) == 0: + return None + + # 두 개의 리스트 병합하는 함수 + def merge(list1, list2): + dummy = ListNode() # 시작노드 + tail = dummy # dummy의 끝을 가리키는 포인터 + + # list1와 list2에 노드가 있을 동안 반복 + while list1 and list2: + # list1값과 list2값 중 더 작은 노드 값을 dummy에 추가 + if list1.val < list2.val: + tail.next = list1 + list1 = list1.next + else: + tail.next = list2 + list2 = list2.next + tail = tail.next + + # 남은 노드들 붙이기 + if list1: + tail.next = list1 + if list2: + tail.next = list2 + + # dummy의 다음이 병합 결과 + return dummy.next + + # 전체 리스트가 하나가 될 때까지 병합 + while len(lists) > 1: + merged = [] + + # 리스트 두 개씩 병합하기 + for i in range(0, len(lists), 2): + list1 = lists[i] + + if i + 1 < len(lists): + list2 = lists[i+1] + else: + list2 = None + + merged.append(merge(list1,list2)) + + # 병합된 리스트로 업데이트 + lists = merged + + # 하나로 병합된 리스트 반환 + return lists[0] diff --git a/search-in-rotated-sorted-array/yyyyyyyyyKim.py b/search-in-rotated-sorted-array/yyyyyyyyyKim.py new file mode 100644 index 000000000..2acf6d6a8 --- /dev/null +++ b/search-in-rotated-sorted-array/yyyyyyyyyKim.py @@ -0,0 +1,29 @@ +class Solution: + def search(self, nums: List[int], target: int) -> int: + + # 회전된 정렬 배열에서 이진탐색(시간복잡도 O(log n)) + left = 0 + right = len(nums)-1 + + while left <= right: + mid = (left+right)//2 + + if nums[mid] == target: + return mid + + # 왼쪽 정렬 + if nums[left] <= nums[mid]: + if nums[left] <= target < nums[mid]: + right = mid - 1 + else: + left = mid + 1 + + # 오른쪽 정렬 + else: + if nums[mid] < target <= nums[right]: + left = mid + 1 + else: + right = mid - 1 + + # 탐색 후에도 타켓을 발견하지 못했다면 -1 반환 + return -1