diff --git a/graph-valid-tree/sungjinwi.py b/graph-valid-tree/sungjinwi.py new file mode 100644 index 000000000..4841e388c --- /dev/null +++ b/graph-valid-tree/sungjinwi.py @@ -0,0 +1,56 @@ +""" + 풀이 : + valid tree를 만족하려면 두 가지 조건이 필요하다 + + 1. 순환이 없어야 한다 + 2. 모든 노드가 연결되어 있어야한다 + + 이 조건을 만족하려면 (vertex 수 - 1) == edge 수 가 필수조건이다 + edge 수가 더 적다면 모든 노드가 연결되지 않고 더 많다면 필연적으로 순환이 존재하기 때문 + 위 조건으로 필터링하고 나서 모든 노드가 연결됐는지지 확인하면 valid tree를 알 수 있다 + 즉, 순환을 가지고 있는지 확인하는 과정이 생략된다 + + - edges를 기반으로 graph를 만든다 + + 노드 개수: N, 간선 개수: E + E == N - 1을 먼저 확인하기 때문에 E는 N에 비례한다 + 따라서 N만 사용 + + TC: O(N) + 모든 node에 대해 dfs호출, edges에 대한 순회도 node수에 비례 + + SC: O(N) + dfs 호출 스택 및 graph는 node 수에 비례 +""" + +from typing import ( + List, +) + +class Solution: + """ + @param n: An integer + @param edges: a list of undirected edges + @return: true if it's a valid tree, or false + """ + def valid_tree(self, n: int, edges: List[List[int]]) -> bool: + # write your code here + if n - 1 != len(edges) : + return False + + graph = [[] for _ in range(n)] + for node, adjcent in edges: + graph[node].append(adjcent) + graph[adjcent].append(node) + + visited = set() + + def dfs(node): + visited.add(node) + for adj in graph[node]: + if adj not in visited: + dfs(adj) + + dfs(0) + + return len(visited) == n diff --git a/maximum-depth-of-binary-tree/sungjinwi.py b/maximum-depth-of-binary-tree/sungjinwi.py new file mode 100644 index 000000000..1e84b57f0 --- /dev/null +++ b/maximum-depth-of-binary-tree/sungjinwi.py @@ -0,0 +1,29 @@ +""" + 풀이: + 재귀함수의 탈출조건은 root가 존재하지 않을 때, return 0 + 그 외에는 left, right에 재귀함수를 호출하여 더 높은 값 + 1을 return 한다 + 가장 깊은 깊이의 maxDepth가 0을 return 하고 밑에서부터 + 1 씩 쌓여서 총 깊이를 return 할 수 있다 + + 노드의 개수: N + + SC : O(N) + + 모든 노드에 대해 순회 + + TC : O(N) + + 모든 노드에 대한 재귀콜스택 + +""" + +# 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: + if not root: + return 0 + return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1 diff --git a/merge-intervals/sungjinwi.py b/merge-intervals/sungjinwi.py new file mode 100644 index 000000000..38531b3f6 --- /dev/null +++ b/merge-intervals/sungjinwi.py @@ -0,0 +1,31 @@ +""" + 풀이 : + 오름차순으로 interval을 정렬 후 ans의 마지막과 interval을 비교 + - 겹치는 구간이 있다면 합치고 + - 없다면 ans에 새로 interval을 추가한다 + + - 정렬을 쓰지 않고 풀었을 때: + 이중for문으로 비교하면서 merged라는 set로 중복검사되지 않도록 유의하면서 합친다 + 겹치는 구간 또한 정렬되어 있지 않기 때문에 좀 더 복잡한 조건으로 비교해야함 + + interval 수 N + + TC : O(N logN) + 정렬하는데 들어가는 시간 N logN + for문 N + + SC : O(N) + sorted(intervals)는 N에 비례, 결과 배열은 최악의 경우 N과 동일일 +""" + + +class Solution: + def merge(self, intervals: List[List[int]]) -> List[List[int]]: + ans = [] + for interval in sorted(intervals): + if not ans: + ans.append(interval) + if interval[0] <= ans[-1][1]: + ans[-1][1] = max(ans[-1][1], interval[1]) + else : + ans.append(interval) + return ans diff --git a/reorder-list/sungjinwi.py b/reorder-list/sungjinwi.py new file mode 100644 index 000000000..7ad127c2f --- /dev/null +++ b/reorder-list/sungjinwi.py @@ -0,0 +1,43 @@ +""" + 풀이 : + list를 순회하면서 deque에 저장하고 순차적으로 앞, 뒤에서 pop하면서 다시 잇는다 + + - 마지막 노드의 next를 None으로 할당해줄 것 + + Node 개수 : N + + TC : O(N) + + SC : O(N) +""" + +from collections import deque + +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reorderList(self, head: Optional[ListNode]) -> None: + """ + Do not return anything, modify head in-place instead. + """ + tmp = head + save = deque() + + while tmp: + save.append(tmp) + tmp = tmp.next + + dummy = ListNode(-1) + tmp = dummy + while save: + tmp.next = save.popleft() + tmp = tmp.next + if (save): + tmp.next = save.pop() + tmp = tmp.next + tmp.next = None + + head = dummy.next