diff --git a/binary-tree-level-order-traversal/KwonNayeon.py b/binary-tree-level-order-traversal/KwonNayeon.py index 431548843..47cc6e9d8 100644 --- a/binary-tree-level-order-traversal/KwonNayeon.py +++ b/binary-tree-level-order-traversal/KwonNayeon.py @@ -10,9 +10,14 @@ - 결과 리스트는 모든 노드의 값을 저장함 풀이방법: -1. queue와 BFS를 활용하여 레벨 순서로 노드를 순회 -2. 각 레벨의 노드들을 별도의 리스트로 모아서 결과에 추가 -3. 각 노드를 처리할 때 그 노드의 자식들을 큐에 추가하여 다음 레벨로 넘어감 +1. 루트가 없으면 빈 리스트 반환 +2. 큐에 루트 넣기 +3. while 큐가 빌 때까지: + - 현재 레벨의 노드 개수 저장 + - 그 개수만큼 노드를 꺼냄 + - 노드의 값 저장 + - 자식이 있으면 큐에 추가 + - 결과에 현재 레벨을 추가 """ # Definition for a binary tree node. # class TreeNode: @@ -44,3 +49,4 @@ def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: result.append(current_level) return result + diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal/KwonNayeon.py b/construct-binary-tree-from-preorder-and-inorder-traversal/KwonNayeon.py index d158f34ea..80a219360 100644 --- a/construct-binary-tree-from-preorder-and-inorder-traversal/KwonNayeon.py +++ b/construct-binary-tree-from-preorder-and-inorder-traversal/KwonNayeon.py @@ -1,19 +1,36 @@ """ Constraints: - 1. 1 <= preorder.length <= 3000 - 2. inorder.length == preorder.length - 3. -3000 <= preorder[i], inorder[i] <= 3000 - 4. preorder and inorder consist of unique values - 5. Each value of inorder also appears in preorder - 6. preorder is guaranteed to be the preorder traversal of the tree - 7. inorder is guaranteed to be the inorder traversal of the tree +1. 1 <= preorder.length <= 3000 +2. inorder.length == preorder.length +3. -3000 <= preorder[i], inorder[i] <= 3000 +4. preorder and inorder consist of unique values +5. Each value of inorder also appears in preorder +6. preorder is guaranteed to be the preorder traversal of the tree +7. inorder is guaranteed to be the inorder traversal of the tree -Time Complexity: - - O(N^2). 각 노드(N)마다 inorder에서 index를 찾는 연산(N)이 필요하고, 각 노드를 한 번씩 방문하여 트리를 구성하기 때문. -Space Complexity: - - O(N). 재귀 호출 스택을 위한 공간이 필요하며, 최악의 경우(한쪽으로 치우친 트리) 재귀 깊이가 N까지 갈 수 있기 때문. -""" +Time Complexity: O(N^2) +- 각 노드(N)마다 inorder에서 index를 찾는 연산(N)이 필요하고, 각 노드를 한 번씩 방문하여 트리를 구성하기 때문. +Space Complexity: O(N) +- 재귀 호출 스택을 위한 공간이 필요하며, 최악의 경우(한쪽으로 치우친 트리) 재귀 깊이가 N까지 갈 수 있기 때문. + +아이디어: +- preorder: 루트의 위치를 알려줌 +- inorder: 왼쪽/오른쪽 서브트리를 구분해줌 +풀이방법: +1. 빈 배열일 때 None 반환 +2. root, mid 변수 생성 (mid - 왼쪽/오른쪽 서브트리 경계) +3. 재귀를 활용하여 서브트리 분할 + +예시: +- Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] +""" +# 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 buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: if not preorder or not inorder: diff --git a/longest-palindromic-substring/KwonNayeon.py b/longest-palindromic-substring/KwonNayeon.py index 81a367645..52331a116 100644 --- a/longest-palindromic-substring/KwonNayeon.py +++ b/longest-palindromic-substring/KwonNayeon.py @@ -3,17 +3,15 @@ - 1 <= s.length <= 1000 - s consist of only digits and English letters. + +- 문자열의 시작값과 끝값을 이용하여 가장 긴 팰린드롬으로 업데이트하는 방식 + Time Complexity: O(n^3) - 모든 부분 문자열을 구할 때 O(n^2) - 각 부분 문자열이 팰린드롬인지를 알아낼 때 O(n) Space Complexity: O(1) - -Note: -- 더 효율적인 방법 생각해보기/찾아보기 """ -# Solution 1: Brute force -# 문자열의 시작값과 끝값을 이용하여 가장 긴 팰린드롬으로 업데이트하는 방식 class Solution: def longestPalindrome(self, s: str) -> str: longest_palindrome = "" @@ -29,3 +27,42 @@ def longestPalindrome(self, s: str) -> str: longest_palindrome = substr return longest_palindrome + +""" + +- 투 포인터를 활용하여 중심에서부터 팰린드롬 여부 체크 + +Time Complexity: O(n^2) +- 메인 루프: O(n) - 각 위치 i에 대해 반복 +- 각 루프에서 expandAroundCenter 호출: 최악의 경우 O(n) - 전체 문자열까지 확장 가능 + +Space Complexity: O(1) +- 추가 변수를 사용하지 않음 +""" +class Solution: + def longestPalindrome(self, s: str) -> str: + if not s: + return "" + + start = 0 + max_len = 1 + + for i in range(len(s)): + + len1 = self.expandAroundCenter(s, i, i) + len2 = self.expandAroundCenter(s, i, i+1) + + current_max = max(len1, len2) + + if current_max > max_len: + max_len = current_max + start = i - (current_max - 1) // 2 + + return s[start:start + max_len] + + def expandAroundCenter(self, s, left, right): + while left >= 0 and right < len(s) and s[left] == s[right]: + left -= 1 + right += 1 + + return right - left - 1 diff --git a/subtree-of-another-tree/KwonNayeon.py b/subtree-of-another-tree/KwonNayeon.py index ac4acb616..b73b8c326 100644 --- a/subtree-of-another-tree/KwonNayeon.py +++ b/subtree-of-another-tree/KwonNayeon.py @@ -14,15 +14,11 @@ 풀이방법: 1. Base case: - - subRoot가 없는 경우 True + - subRoot가 없는 경우 True (빈 트리는 모든 트리의 서브트리이기 때문) - root가 빈 트리이고, subRoot가 있는 경우 False -2. 서브트리가 동일한지를 확인하는 재귀 함수 활용: - - isSameTree()를 사용하여 두 트리가 동일한지 판단 - - 현재 노드부터 시작해 subRoot와 같은지 확인 - - 같지 않다면 왼쪽과 오른쪽 서브트리를 다시 검사함 -3. 재귀적으로 서브트리를 탐색 - - 현재 노드에서 시작하는 서브트리가 subRoot와 같다면 True - - 아니라면 왼쪽 또는 오른쪽 서브트리에서 계속 탐색 +2. 두 단계로 나누어 처리: + - isSameTree(): 두 트리가 동일한지 비교 + - isSubtree(): 현재 노드가 안 맞으면 왼쪽/오른쪽 서브트리에서 재귀 탐색 """ # Definition for a binary tree node. # class TreeNode: