diff --git a/container-with-most-water/EcoFriendlyAppleSu.kt b/container-with-most-water/EcoFriendlyAppleSu.kt new file mode 100644 index 000000000..ff9271806 --- /dev/null +++ b/container-with-most-water/EcoFriendlyAppleSu.kt @@ -0,0 +1,59 @@ +package leetcode_study + +/* +* 주어진 높이에서 만들 수 있는 가장 큰 면적을 구하는 문제. +* Brute force로 모든 경우의 수를 따져가며 최대 면적을 구하는 방법. +* 주어진 높이(n)의 개수는 2 보다 크거가 같고 10^4 보다 작거나 같음. +* 이중 Loop으로 해결할 경우 시간 초과 발생 (10^8 이하로 해결해야 제한 시간 안으로 문제 해결 가능) +* +* 시간 복잡도: O(n^2) +* -> 두 개의 서로 다른 높이를 구하기 위해 이중 반복문 실행: O(n^2) +* 공간 복잡도: O(1) +* -> 추가 메모리 사용 없음. +* */ +fun maxArea01(height: IntArray): Int { + var maxValue = 0 + for (i in 0 until height.size) { + for (j in i + 1 until height.size) { + // 너비는 두 선분 사이의 거리 + val width = j - i + // 높이는 두 선분 중 작은 값 + val containerHeight = Math.min(height[i], height[j]) + // 면적 계산 + val area = width * containerHeight + // 최대값 갱신 + maxValue = Math.max(maxValue, area) + } + } + return maxValue +} + +/* +* 이중 포인터를 사용한 문제 풀이. +* 결과에 영향을 주는 조건과 요소 +* -> 높이의 위치를 나타내는 왼쪽값과 오른쪽 값에서 두 값 중 작은 값이 높이가 될 수 있음. +* -> 오른쪽의 값은 왼쪽 값보다 작을 수 없음. +* -> 너비 값은 오른쪽 인덱스에서 왼쪽 인덱스를 뺀 값임. +* +* 시간 복잡도: O(n) +* -> 주어진 높이 배열에서 양쪽 끝 값을 증감/가감 해가며 반복 진행: O(n) +* 공간 복잡도: O(1) +* -> 추가 메모리 사용 없음. +* */ +fun maxArea02(height: IntArray): Int { + var maxValue = 0 + var left = 0 + var right = height.size - 1 + while (left <= right) { + val width = right - left + val containerHeight = Math.min(height[left], height[right]) + val area = width * containerHeight + maxValue = Math.max(maxValue, area) + if (height[left] < height[right]) { + left++ + } else { + right-- + } + } + return maxValue +} diff --git a/design-add-and-search-words-data-structure/EcoFriendlyAppleSu.kt b/design-add-and-search-words-data-structure/EcoFriendlyAppleSu.kt new file mode 100644 index 000000000..778470299 --- /dev/null +++ b/design-add-and-search-words-data-structure/EcoFriendlyAppleSu.kt @@ -0,0 +1,61 @@ +package leetcode_study + + +/* +* 단어 사전을 만드는 문제. (찾는 단어는 wildcard가 포함될 수 있음) +* https://www.youtube.com/watch?v=TohdsR58i3Q 동영상 참조 +* trie 알고리즘을 사용한 문제 해결 +* 시간 복잡도: O(L * 26) +* -> addWord() 의 경우, 각 노드는 최대 26개의 노드를 가질 수 있으며 단어의 길이가 L이라면 O(L)의 시간 소요: O(L) +* -> searchWord() 의 경우, 최악의 경우 모든 자식의 노드를 탐색해야 하므로 26(알파벳 수) 번의 탐색 진행: O(L * 26) +* 공간 복잡도: O(n * L) +* -> n 개의 단어, 평균적 단어 길이가 L일 경우 트리 노드에 저장된 노드의 수는 O(n * L) +* */ +class WordDictionary() { + // Trie 노드 클래스 + private class TrieNode { + val children: MutableMap = mutableMapOf() + var endOfWord: Boolean = false + } + + private val root = TrieNode() + + // 단어를 트라이에 추가 + fun addWord(word: String) { + var currentNode = root + for (char in word) { + if (!currentNode.children.containsKey(char)) { + currentNode.children[char] = TrieNode() // 해당 문자에 대한 새로운 노드 생성 + } + currentNode = currentNode.children[char]!! // point out next trie node + } + currentNode.endOfWord = true // 단어의 끝을 표시 + } + + // 주어진 패턴을 검색 + fun search(word: String): Boolean { + return searchHelper(word, 0, root) + } + + // 재귀적으로 단어를 검색하는 헬퍼 함수 + private fun searchHelper(word: String, index: Int, node: TrieNode): Boolean { + if (index == word.length) { + return node.endOfWord // 단어의 끝에 도달했으면 해당 노드가 단어의 끝인지 확인 + } + + val char = word[index] + + if (char == '.') { // '.'이면 모든 자식 노드에 대해 탐색 + for (childNode in node.children.values) { + if (searchHelper(word, index + 1, childNode)) { + return true + } + } + return false // '.'을 처리했지만 일치하는 노드가 없으면 false + } else { + // 현재 문자가 존재하는 자식 노드로 계속 탐색 + val childNode = node.children[char] ?: return false + return searchHelper(word, index + 1, childNode) + } + } +} diff --git a/valid-parentheses/EcoFriendlyAppleSu.kt b/valid-parentheses/EcoFriendlyAppleSu.kt new file mode 100644 index 000000000..a001a851f --- /dev/null +++ b/valid-parentheses/EcoFriendlyAppleSu.kt @@ -0,0 +1,32 @@ +package leetcode_study + +/* +* Pair Bracket 판별 문제 +* 스택의 LIFO의 성질을 사용해 문제 해결 +* 시간 복잡도: O(n) +* -> 문자열 길이만큼 반복 진행: O(n) +* 공간 복잡도: O(n) +* -> 주어진 문자열 길이만큼 공간 필요: O(n) +* */ +fun isValid(s: String): Boolean { + val stack = mutableListOf() + + for (element in s) { + if (element == ')' || element == ']' || element == '}') { + if (stack.isEmpty()) { + return false + } else if (stack.last() == '(' && element == ')') { + stack.removeAt(stack.lastIndex) + } else if (stack.last() == '[' && element == ']') { + stack.removeAt(stack.lastIndex) + } else if (stack.last() == '{' && element == '}') { + stack.removeAt(stack.lastIndex) + } else { + return false + } + } else { + stack.add(element) + } + } + return stack.isEmpty() +}