Skip to content

[친환경사과] Week 2 #718

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 5 commits into from
Dec 22, 2024
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
104 changes: 104 additions & 0 deletions 3sum/EcoFriendlyAppleSu.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package leetcode_study

/**
* 주어진 배열의 세 원소의 합이 0인 경우를 구하는 문제. (세 개의 값의 결과는 중복되지 않음)
*
* 주어진 조건
* 3 <= nums.length <= 3000
* -105 <= nums[i] <= 105
*/

/**
* case01. 조합을 사용한 풀이.
* 시간 초과 발생 이유
* -> 모든 가능한 세 개의 조합을 생성하기 때문에 발생.
* 시간 복잡도:
* -> 세 개의 조합 생성 과정: O(n * (n-1) * (n-2)) / 3. 최악의 경우 n = 3000, 4.5 억개 조합 생성
* -> 세 개의 조합 결과 sorting 과정: O(klogk). k = 3
* -> 결과값을 필터링해 합이 0인 배열을 필터하는 과정: O(n)
* 나머지 연산이 세 개의 조합 생성 과정에 영향을 받아 계산 횟수 증가.
*
* 공간 복잡도:
* -> 각 조합을 모두 저장: O(n^3)
*/
fun threeSumUseCombination(nums: IntArray): List<List<Int>> {
// 결과를 담을 Set 자료구조
val processResult = mutableSetOf<List<Int>>()

// 주어진 배열의 크기를 담는 변수
val maxNumber = nums.size

// 조합 배열의 크기
val givenSize = 3

// 나타낼 인덱스를 구하는 배열 초기화
val indices = IntArray(givenSize)
for (i in 0 until givenSize) {
indices[i] = i
}

while (indices[givenSize - 1] < maxNumber) {
processResult.add(indices.map { nums[it] }.sorted())
var i = givenSize - 1

while (i >= 0 && indices[i] == i + maxNumber - givenSize) {
i--
}

if (i >= 0) {
indices[i]++
for (j in i + 1 until givenSize) {
indices[j] = indices[j-1] + 1
}
} else break
}

return processResult.filter { it.sum() == 0 }
}

/**
* case02. 투 포인터를 사용한 풀이
* 조합을 사용한 풀이와 달리 시간 초과가 발생하지 않음. O(n^3)의 시간 복잡도를 O(n^2)으로 줄임
*
* 시간 복잡도:
* -> 주어진 숫자 배열 오름차순으로 정렬: O(nlogn)
* -> 세 개의 숫자를 더하는 로직
* -> 외부 반복문을 통해 주어진 배열 전체 조회: O(n)
* -> 내부 반복문을 통해 start to last index 순회: O(n)
* -> O(n^2)
* ∴ O(nlogn) + O(n^2) => O(n^2)
*
* 공간 복잡도:
* -> 주어진 숫자 배열의 정렬을 담는 공간 필요: O(n)
*/
fun threeSum(nums: IntArray): List<List<Int>> {
val processResult = mutableListOf<List<Int>>()
val sortedNums = nums.sorted()

for (i in sortedNums.indices) {
if (i > 0 && sortedNums[i] == sortedNums[i-1]) continue

var startIndex = i + 1
var lastIndex = sortedNums.size - 1

while (startIndex < lastIndex) {
val sum = sortedNums[i] + sortedNums[startIndex] + sortedNums[lastIndex]
when {
sum == 0 -> {
processResult.add(listOf(sortedNums[i], sortedNums[startIndex], sortedNums[lastIndex]))
while (startIndex < lastIndex && sortedNums[startIndex] == sortedNums[startIndex + 1]) startIndex++
while (startIndex < lastIndex && sortedNums[lastIndex] == sortedNums[lastIndex - 1]) lastIndex--
startIndex++
lastIndex--
}
sum < 0 -> {
startIndex++
}
else -> {
lastIndex--
}
}
}
}
return processResult
}
24 changes: 24 additions & 0 deletions climbing-stairs/EcoFriendlyAppleSu.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package leetcode_study

/**
* 계단에 올라갈 수 있는 경우의 수 구하는 방법
* 시간 복잡도: O(n)
* -> 주어진 횟수 만큼 반복 진행
* 공간 복잡도: O(k)
* -> 주어진 계단 수 만큼 횟수를 저장할 공간 필요
*/
fun climbStairs(n: Int): Int {
val step = IntArray(n+1)

if (n == 1) {
return 1
}
step[1] = 1
step[2] = 2

for (i in 3 until step.size) {
step[i] = step[i-1] + step[i-2]
}

return step[n]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package leetcode_study

/**
* 전위 순회, 중위 순회를 통한 원본 Binary Tree를 구하는 문제
*
* 전위 순회 탐색 순서 : 루트 -> 왼쪽 서브 트리 -> 오른쪽 서브 트리
* 중위 순회 탐색 순서 : 왼쪽 서브 트리 -> 루트 -> 오른쪽 서브 트리
* 탐색은 동일한 Binary Tree를 두고 진행되기 때문에 배열의 길이는 같습니다.
*
* 시간 복잡도: O(n^2)
* -> Ary RootNode Index 를 찾는 과정: O(n)
* -> 재귀 안에서 RootNode Index 를 찾는 과정: O(n)
* --> 두 계의 과정은 별도로 존재하는 것이 아닌 내부적으로 일어나기 때문에 O(n) * O(n). 즉, O(n^2)의 시간 복잡도가 소요됨
*
* 공간 복잡도: O(n) or O(logn)
* -> 재귀를 통할 때마다 배열이 새로 생성. 각 노드에 대해 배열이 나뉘므로 O(n)의 공간 복잡도를 가짐
* -> 만약 Binary Tree가 한 쪽으로 치우지지 않은 Balanced Binary Tree라면 O(logn)의 공간 복잡도를 가짐.
Comment on lines +15 to +17
Copy link
Contributor

Choose a reason for hiding this comment

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

�최악의 경우를 생각하여 O(n)으로 처리하면 되지 않을까 싶습니다 :)

*/
fun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? {
if (preorder.isEmpty() || inorder.isEmpty()) return null

// 왼쪽 오른쪽 분류의 기준이 되는 rootValue를 구하는 과정
val rootValue = preorder[0]
val rootNode = TreeNode(rootValue)

// root를 기준으로 왼쪽, 오른쪽 subTree를 구성
val pivotValue = inorder.indexOf(rootValue)
val leftInOrder = inorder.slice(0 until pivotValue)
val rightInOrder = inorder.slice(pivotValue + 1 until inorder.size)

// 왼쪽, 오른쪽 subTree를 기준으로 leftPreOrder, rightPreOrder 구성
val leftPreOrder = preorder.slice(1 until leftInOrder.size + 1)
val rightPreOrder = preorder.slice(leftInOrder.size + 1 until preorder.size)

// 재귀를 통한 subTree 생성
rootNode.left = buildTree(leftPreOrder.toIntArray(), leftInOrder.toIntArray())
rootNode.right = buildTree(rightPreOrder.toIntArray(), rightInOrder.toIntArray())

return rootNode
}

class TreeNode(val value: Int, ) {
var left: TreeNode? = null
var right: TreeNode? = null
}
35 changes: 35 additions & 0 deletions valid-anagram/EcoFriendlyAppleSu.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package leetcode_study

/**
* 문장의 문자 순서를 바꾸어 새로운 단어나 문장을 만들 수 있는지 판별하는 문제
* 시간 복잡도: O(n)
* -> 주어진 문자열을 순회하며 Map 자료구조에 값을 채워넣는 과정: O(n)
* -> 알파벳 문자열 세팅 과정: O(1)
* -> Map<알파벳, 빈도> 초기화 과정: O(1)
* -> 알파벳 비교 과정: O(1)
* O(1) + O(1) + O(1) + O(n) => O(n)
*
* 공간 복잡도: O(1)
* -> 알파벳 빈도수를 저장 Map: O(1)
*/
fun isAnagram(s: String, t: String): Boolean {
val alphaArray = CharArray(26) { 'a' + it}

if (s.length != t.length) return false

val sMap = alphaArray.associateWith { 0 }.toMutableMap()
val tMap = alphaArray.associateWith { 0 }.toMutableMap()

for (i in s.indices) {
sMap[s[i]] = sMap.getValue(s[i]).plus(1)
tMap[t[i]] = tMap.getValue(t[i]).plus(1)
}

for (alphabet in alphaArray) {
if (sMap[alphabet] != tMap[alphabet]) {
return false
}
}

return true
}
Loading