diff --git a/container-with-most-water/Jay-Mo-99.py b/container-with-most-water/Jay-Mo-99.py new file mode 100644 index 000000000..2ba05da40 --- /dev/null +++ b/container-with-most-water/Jay-Mo-99.py @@ -0,0 +1,40 @@ + #해석 + #s는 start index, e는 ending index로 할당한다. + #area 에 (e-s)*min(height[e], height[s]) 로 면적의 넓이를 구한다. + #만약 height[s]가 height[e] 보다 작다면, 현 area보다 더 큰 결괏값을 위해 변화를 준다. + # (e-s)에서 e를 줄어들면 필연적으로 area 값이 기존보다 적어진다. 따라서 s에 1을 더해 인덱스를 오른쪽으로 이동시켜 height[s] 에 변화를 준다. + #그 외의 상황에는 height[e]를 변화시키기 위해 e에 1를 빼 왼쪽 인덱스로 이동시킨다. + #해당 루프는 s가 e보다 작을때 작용된다. 만약 s의 증가와 e의 감소로 두 변수가 마주치면 종료한 후 max_area를 return시킨다. + + + + #Big O + #- N: height의 element 갯수 + + #Time Complexity: O(N) + #- while : s와 e가 만날때까지 최대 N번 반복된다. 각 반복에서의 연산들은 O(1)에 해당된다. -> O(N) + + + #Space Complexity: O(1) + #- s,e,max_area: 변수는 상수로 작용된다 -> O(1) + #### + # + # +class Solution(object): + def maxArea(self, height): + """ + :type height: List[int] + :rtype: int + """ + max_area = 0 #Saving for answer + s,e=0,len(height)-1 #Assign the first index and last index + while s TrieNode 인스턴스). +# 2) is_end_of_word: 현재 노드가 단어의 끝인지 나타내는 Boolean 값. + +# 1. WordDictionary 클래스 정의: +# - WordDictionary 클래스는 Trie 자료구조를 사용하여 단어를 저장(addWord)하고 탐색(search)한다. + +# 1-1. __init__ 함수: +# - root는 TrieNode 클래스로 생성된 인스턴스를 가진다. +# - Trie 자료구조의 시작점(루트 노드) 역할을 한다. + +# 1-2. addWord 함수: +# 1) 루트 노드(self.root)에서 시작. +# 2) 단어의 각 문자를 순회하며: +# - 현재 노드의 children에 문자가 없으면, 새 TrieNode를 생성해 추가. +# - 현재 노드를 해당 문자의 자식 노드로 이동. +# 3) 단어의 마지막 문자를 처리한 후, 해당 노드의 is_end_of_word를 True로 설정. + + +# 1-3. search 함수: +# - 주어진 단어가 Trie에 존재하는지 확인하는 함수. +# - 와일드카드 문자(.)를 처리할 수 있다. +# - 내부적으로 dfs(깊이 우선 탐색) 함수를 사용하여 트라이를 탐색. +# - dfs(index, node): +# 1) 종료 조건: index가 단어 길이에 도달하면, 현재 노드의 is_end_of_word 반환. +# 2) 현재 문자가 '.'인 경우: +# - 현재 노드의 모든 자식 노드에 대해 dfs를 호출. +# - 하나라도 True를 반환하면 True 반환. +# 3) 현재 문자가 일반 문자인 경우: +# - 자식 노드에 문자가 없으면 False 반환. +# - 자식 노드로 이동해 dfs를 재귀 호출. + + + + #Big O + # - N: 저장된 모든 단어의 총 문자 수 (Trie에 저장된 모든 문자의 개수). + # - C: 알파벳의 개수 (영어 기준 최대 26). + + #Time Complexity: O(N) + #- addWord함수 : N에 기반하여 단어 추가 + #- searchWord 함수: + # - 일반 탐색: O(n), n은 단어의 길이. + # - 와일드카드 탐색: 최악의 경우 O(C^N), + # - C는 알파벳 개수 (최대 26). + # - N은 단어의 길이. 와일드카드 문자가 많을수록 모든 경로를 탐색해야 할 수도 있음. + + # - Space Complexity: O(N × C) + # + # - 각 노드는: + # 1) children 딕셔너리를 통해 자식 노드를 저장 (메모리 사용). + # 2) is_end_of_word 변수 (Boolean 값, O(1)). + # - Trie에 저장된 단어의 문자 수가 많을수록 메모리 사용량 증가. + +class TrieNode: + def __init__(self): + self.children = {} #알파벳 a부터 z까지를 자식으로 가짐, 크기 26의 배열이나 딕셔너리를 사용. + self.is_end_of_word = False #어떤 단어의 끝인지 나타내는 Boolean 값 + #예를 들어, "note"이라는 단어의 'e'에 해당하는 노드의 is_end_of_word가 True, 'n' + +class WordDictionary: + def __init__(self): + self.root = TrieNode() # WD로 생성된 인스턴스.root = TrieNode 인스턴스 + + def addWord(self, word: str) -> None: + node = self.root #node에 self.root를 부여 + for char in word: # 매개변수 word를 하나씩 순회하며 char에 저장 (예: word="note" -> char="n", "o", "t", "e") + if char not in node.children: # 만약 char가 현재 노드의 자식 노드 목록에 없다면 + node.children[char] = TrieNode() + #node.children[char]을 TrideNode 인스턴스로 생성 + # self.root.children = { + # "n": TrieNode() # "n" 키가 추가되고, 값으로 새로운 TrieNode 인스턴스가 들어감 + # } + + #Example1: + #root + #└── "n" (children={}, is_end_of_word=False) + + #Example2: + #└── "n" (children={}, is_end_of_word=False) + # └── "o" (children={}, is_end_of_word=False) + node = node.children[char] #node를 현 node의 children[char]로 이동 + #Example1: + # node = node.children["n"] + + #Example2: + # node = node.children["o"] + node.is_end_of_word = True + #After for loop, 끝 노드의 is_end_of_word를 True로 전환 + + #Example 4: + #root + #└── "n" + #└── "o" + #└── "t" + #└── "e" (children={}, is_end_of_word=True) + + def search(self, word: str) -> bool: + def dfs(index, node): # DFS 함수 정의 + # 1) 종료 조건: 모든 문자를 탐색한 경우 + if index == len(word): + return node.is_end_of_word # 단어 끝 여부 반환 + # 2) 현재 문자 처리 + char = word[index] + if char == '.': # 2-1) 와일드카드인 경우 + for child in node.children.values(): # 모든 자식 노드 탐색 + if dfs(index + 1, child): #dfs를 재귀호출 하여 다음 노드로 탐색 재개 + return True #재귀 이후에 있으면 True + return False #없으면 False + else: # 2-2) 일반 문자 처리 + if char not in node.children: # 현재 문자가 자식 노드에 없는 경우 False + return False + return dfs(index + 1, node.children[char]) # 다음 노드로 이동하여 탐색 + + return dfs(0, self.root) + #1. def dfs를 self.root 위치에서 첫 호출. + + + + diff --git a/valid-parentheses/Jay-Mo-99.py b/valid-parentheses/Jay-Mo-99.py new file mode 100644 index 000000000..46432ae3b --- /dev/null +++ b/valid-parentheses/Jay-Mo-99.py @@ -0,0 +1,57 @@ + #해석 + #매개변수 string s의 각 character인 c 가 open bracket이면 temp 리스트에 추가한다. + #c가 close bracket이면 temp의 마지막 element와 짝이 맞는지 검사한다. 짝이 아니거나 temp에 아무 요소도 없으면 return false + #검사 이후 temp에 잔여 요소가 남아있으면 짝이 맞지 않았다는 뜻이니 return false, 아닐 경우 return true + # + + #Big O + #- N: 문자열 s의 길이 + + #Time Complexity: O(N) = O(N) + O(1) + #- for c in s : string s의 character의 수 만큼 진행된다. -> O(N) + #-temp.append(c), temp.pop() : 리스트 연산은 상수 취급 -> O(1) + + #Space Complexity: O(N) + #- temp : list temp은 최대 string s의 character수 만큼 요소를 저장할 가능성이 있다. + + +class Solution(object): + def isValid(self, s): + """ + :type s: str + :rtype: bool + """ + temp = [] + for c in s: + #If c is Open bracket, append to the list + if (c == "(") or (c=="{") or (c=="["): + temp.append(c) + #If C is Close bracket, Check the close bracket pairs with last elememt of temp list + else: + #There's no element in the tmep, Return false + if(len(temp)==0): + return False + + if(c==")") and (temp.pop()=="("): + continue + if(c=="}") and (temp.pop()=="{"): + continue + if(c=="]") and (temp.pop()=="["): + continue + else: + return False + + #After loop, Check temp is empty or not. + #If all c of s is pairs each other, the temp list is empty. + if (len(temp) == 0) : + return True + else: + return False + + + + + + + +