Skip to content

[친환경사과] Week 6 #900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions container-with-most-water/EcoFriendlyAppleSu.kt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석이 꼼꼼히 작성되어 있어서 리뷰하는 데 큰 도움이 되었어요.
더 나은 방법 찾으시는 모습이 멋지네요! 😃

Original file line number Diff line number Diff line change
@@ -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
Comment on lines +43 to +58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로직 멋지네요! 깔끔하고 좋아요 👍

}
61 changes: 61 additions & 0 deletions design-add-and-search-words-data-structure/EcoFriendlyAppleSu.kt
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오! Trie 한 노드에서 가능한 자식 노드는 알파벳 개수 최대 26개로 제한되는군요!
중복된 알파벳은 기존 노드 재활용한다는 점 덕분에 새로 배워갑니다!
알려주셔서 감사합니다 👍

* -> searchWord() 의 경우, 최악의 경우 모든 자식의 노드를 탐색해야 하므로 26(알파벳 수) 번의 탐색 진행: O(L * 26)
* 공간 복잡도: O(n * L)
* -> n 개의 단어, 평균적 단어 길이가 L일 경우 트리 노드에 저장된 노드의 수는 O(n * L)
* */
class WordDictionary() {
// Trie 노드 클래스
private class TrieNode {
val children: MutableMap<Char, TrieNode> = 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)
}
}
}
32 changes: 32 additions & 0 deletions valid-parentheses/EcoFriendlyAppleSu.kt
Original file line number Diff line number Diff line change
@@ -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<Char>()

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
}
Comment on lines +15 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

괄호 짝인지 비교한 뒤 stack에서 제거 하는 로직이 반복되고 있어서,
괄호 짝을 객체나 Map에 정의한 뒤 키 값에 대응하는 값을 찾으면 중첩을 좀 더 줄일 수 있을 것 같아요
코틀린이 낯설어서 자바스크립트 코드 예시 첨부합니다 ~

  const matchingBrackets: Record<string, string> = {
    ")": "(",
    "}": "{",
    "]": "[",
  };

} else {
stack.add(element)
}
}
return stack.isEmpty()
}
Loading