diff --git a/longest-palindromic-substring/mangodm-web.py b/longest-palindromic-substring/mangodm-web.py new file mode 100644 index 000000000..526be98db --- /dev/null +++ b/longest-palindromic-substring/mangodm-web.py @@ -0,0 +1,30 @@ +class Solution: + def is_palindrome(self, s: str) -> bool: + return s == s[::-1] + + def longestPalindrome(self, s: str) -> str: + """ + - Idea: 아래의 방법으로 주어진 문자열에서 가장 긴 팰린드롬을 찾는다. + 1. 모든 가능한 부분 문자열 생성 + 2. 각 부분 문자열이 팰린드롬인지 확인 + 3. 가장 긴 팰린드롬을 저장하고 반환 + - Time Complexity: O(n^3). n은 문자열의 길이 + 모든 부분 문자열을 구하는데 O(n^2), 각 부분 문자열이 팰린드롬인지 알아내는데 O(n). + 결국 O(n^3)의 시간이 소요된다. + - Space Complexity: O(n). n은 문자열의 길이 + 팰린드롬인지 확인할 때 문자열 슬라이싱을 사용하는데, + 최악의 경우 부분 문자열의 길이가 입력 문자열의 길이와 같아 + 공간 복잡도는 O(n)이다. + """ + + result = s[0] + + for i in range(len(s) - 1): + for j in range(i + 1, len(s) + 1): + if j - i <= len(result): + continue + + if self.is_palindrome(s[i:j]) and (j - i) > len(result): + result = s[i:j] + + return result diff --git a/subtree-of-another-tree/mangodm-web.py b/subtree-of-another-tree/mangodm-web.py new file mode 100644 index 000000000..0f2f2c05a --- /dev/null +++ b/subtree-of-another-tree/mangodm-web.py @@ -0,0 +1,47 @@ +from typing import Optional + + +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + +class Solution: + def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool: + if not subRoot: + return True + if not root: + return False + + if self.isSameTree(root, subRoot): + return True + + has_subroot_in_left = self.isSubtree(root.left, subRoot) + has_subroot_in_right = self.isSubtree(root.right, subRoot) + + return has_subroot_in_left or has_subroot_in_right + + def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool: + """ + - Idea: 두 트리를 다음과 같이 노드 단위로 비교한다. + 1. 두 노드가 모두 None이라면 현재 두 트리는 동일 + 2. 두 노드가 None이 아니고 값이 같다면, 왼쪽과 오른쪽 자식 노드를 재귀적으로 비교 + 3. 두 노드가 다르거나 한쪽만 None이면 두 트리는 상이 + - Time Complexity: O(m). m은 더 작은 트리의 노드 수 + 각 노드를 한번씩 방문하므로 O(m) 시간이 걸린다. + - Space Complexity: O(h). h는 더 작은 트리의 높이 + 재귀 호출 스택에 최대 h만큼의 공간이 사용된다. + """ + + if not p and not q: + return True + + if p and q and p.val == q.val: + is_left_equal = self.isSameTree(p.left, q.left) + is_right_equal = self.isSameTree(p.right, q.right) + + return is_left_equal and is_right_equal + + return False diff --git a/validate-binary-search-tree/mangodm-web.py b/validate-binary-search-tree/mangodm-web.py new file mode 100644 index 000000000..cb18ecede --- /dev/null +++ b/validate-binary-search-tree/mangodm-web.py @@ -0,0 +1,37 @@ +from typing import Optional + + +# 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 isValidBST(self, root: Optional[TreeNode]) -> bool: + """ + - Idea: 각 노드 값의 허용 범위를 정하고 재귀적으로 검사한다. + 1. BST의 정의 활용 + 왼쪽 서브트리의 모든 값은 현재 노드 값보다 작고, 오른쪽 서브트리의 모든 값은 현재 노드 값보다 큼. + 2. 초기값의 범위를 (-inf, inf)로 설정 + 3. 각 노드의 값을 검사하고, 범위를 업데이트해서 재귀적으로 서브 트리 확인 + - Time Complexity: O(n). n은 트리의 노드 수 + 모든 노드를 한번씩 방문한다. + - Space Complexity: O(h). h는 트리의 높이 + 재귀 호출 스택이 트리의 높이만큼 공간을 필요로 한다. + 편향된 트리라면 O(n)이 필요하다. + """ + + def isValid(node: Optional[TreeNode], low: float, high: float) -> bool: + if not node: + return True + if not (node.val < high and node.val > low): + return False + + return isValid(node.left, low, node.val) and isValid( + node.right, node.val, high + ) + + return isValid(root, float("-inf"), float("inf"))