-
Notifications
You must be signed in to change notification settings - Fork 125
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
[정현준] 4주차 답안 제출 #410
Merged
Merged
[정현준] 4주차 답안 제출 #410
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package leetcode_study | ||
|
||
import io.kotest.matchers.shouldBe | ||
import org.junit.jupiter.api.Test | ||
import kotlin.math.max | ||
|
||
class `longest-consecutive-sequence` { | ||
fun longestConsecutive(nums: IntArray): Int { | ||
if (nums.isEmpty()) return 0 | ||
return usingUnionFind(nums) | ||
} | ||
|
||
/** | ||
* 1. 배열을 정렬하여 순서대로 순회하며 연속 수열 길이를 확인한다. | ||
* TC: O(n * log(n)), SC: O(1) | ||
*/ | ||
private fun usingSort(nums: IntArray): Int { | ||
nums.sort() | ||
|
||
var (length, maxLength) = 1 to 0 | ||
for (index in 0 until nums.size - 1) { | ||
if (nums[index] == nums[index + 1]) { | ||
continue | ||
} else if (nums[index] + 1 == nums[index + 1]) { | ||
length++ | ||
} else { | ||
maxLength = max(length, maxLength) | ||
length = 1 | ||
} | ||
} | ||
return max(length, maxLength) | ||
} | ||
|
||
/** | ||
* 2. Set의 자료구조를 활용하여 가장 작은 값부터 while문을 통한 최대 증가 값을 반환한다. | ||
* TC: O(n), SC: O(n) | ||
*/ | ||
private fun usingSet(nums: IntArray): Int { | ||
val numberSet = nums.toSet() | ||
var maxLength = 0 | ||
|
||
for (number in nums) { | ||
if (numberSet.contains(number - 1)) { | ||
continue | ||
} | ||
var length = 1 | ||
while (numberSet.contains(number + length)) { | ||
length++ | ||
} | ||
maxLength = max(maxLength, length) | ||
} | ||
|
||
return maxLength | ||
} | ||
|
||
/** | ||
* 3. Union-Find | ||
* TC: O(n), SC: O(n) | ||
*/ | ||
private fun usingUnionFind(nums: IntArray): Int { | ||
val nodes = mutableMapOf<Int, Int>() | ||
val dsu = DSU(nums.size) | ||
|
||
for ((i,n) in nums.withIndex()) { | ||
if (n in nodes) continue | ||
|
||
nodes[n - 1]?.let { dsu.union(i, it) } | ||
nodes[n + 1]?.let { dsu.union(i, it) } | ||
|
||
nodes[n] = i | ||
} | ||
|
||
return dsu.maxLength() | ||
} | ||
DaleSeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@Test | ||
fun `입력받은 정수 배열의 최대 연속 수열 길이를 반환한다`() { | ||
longestConsecutive(intArrayOf()) shouldBe 0 | ||
longestConsecutive(intArrayOf(100,4,200,1,3,2)) shouldBe 4 | ||
longestConsecutive(intArrayOf(11,23,12,13,14,21)) shouldBe 4 | ||
longestConsecutive(intArrayOf(0,3,7,2,5,8,4,6,0,1)) shouldBe 9 | ||
longestConsecutive(intArrayOf(11,64,43,12,13,10,9,8,7)) shouldBe 7 | ||
} | ||
} | ||
|
||
class DSU(val n: Int) { | ||
private val parent = IntArray(n) { it } | ||
private val size = IntArray(n) { 1 } | ||
|
||
private fun find(x: Int): Int { | ||
if (parent[x] != x) | ||
parent[x] = find(parent[x]) | ||
return parent[x] | ||
} | ||
|
||
fun union(x: Int, y: Int) { | ||
val root = find(x) | ||
val child = find(y) | ||
if(root != child) { | ||
parent[child] = root | ||
size[root] += size[child] | ||
} | ||
} | ||
|
||
fun maxLength(): Int { | ||
var res = 0 | ||
for (i in parent.indices) { | ||
if (parent[i] == i) | ||
res = maxOf(res, size[i]) | ||
} | ||
return res | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package leetcode_study | ||
|
||
import io.kotest.matchers.shouldBe | ||
import org.junit.jupiter.api.Test | ||
import kotlin.math.max | ||
import kotlin.math.min | ||
|
||
class `maximum-product-subarray` { | ||
|
||
/** | ||
* 현재의 값, 이전 위치의 최대 누적곱, 이전 위치의 최소 누적곱 이 세 개를 비교하여 한 번의 순회로 최대 값을 반환한다. | ||
* 음수와 음수가 곱해져 최대 값이 도출될 수 있기에 DP 배열을 두 개 생성한다. | ||
* TC: O(n), SC: O(n) | ||
*/ | ||
fun maxProduct(nums: IntArray): Int { | ||
val (min, max) = IntArray(nums.size) { 11 }.apply { this[0] = nums[0] } to IntArray(nums.size) { -11 }.apply { this[0] = nums[0] } | ||
DaleSeo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var result = max(-11, nums[0]) | ||
for (index in 1 until nums.size) { | ||
max[index] = max(max(nums[index], nums[index] * max[index - 1]), nums[index] * min[index - 1]) | ||
min[index] = min(min(nums[index], nums[index] * max[index - 1]), nums[index] * min[index - 1]) | ||
result = max(max(min[index], max[index]), result) | ||
} | ||
|
||
return result | ||
} | ||
|
||
@Test | ||
fun `입력받은 정수 배열의 가장 큰 곱을 반환한다`() { | ||
maxProduct(intArrayOf(2,3,-2,4)) shouldBe 6 | ||
maxProduct(intArrayOf(-2,0,-1)) shouldBe 0 | ||
maxProduct(intArrayOf(-10)) shouldBe -10 | ||
maxProduct(intArrayOf(-2,3,-4)) shouldBe 24 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package leetcode_study | ||
|
||
import io.kotest.matchers.shouldBe | ||
import org.junit.jupiter.api.Test | ||
|
||
class `missing-number` { | ||
|
||
fun missingNumber(nums: IntArray): Int { | ||
return usingSum(nums) | ||
} | ||
|
||
/** | ||
* 1. 배열을 추가로 생성하여 존재하는 정수의 인덱스에 true를 저장하여, false인 인덱스를 반환한다. | ||
* TC: O(n), SC: O(n) | ||
*/ | ||
private fun usingIndex(nums: IntArray): Int { | ||
val existed = BooleanArray(nums.size + 1) | ||
nums.forEach { existed[it] = true } | ||
|
||
existed.forEachIndexed { i, e -> | ||
if (!e) return i | ||
} | ||
return -1 | ||
} | ||
|
||
/** | ||
* 2. 0부터 정수 배열의 사이즈만큼 정수를 합산하여 기대하는 합산과 뺀 결과를 반환한다. | ||
* TC: O(n), SC: O(1) | ||
*/ | ||
private fun usingSum(nums: IntArray): Int { | ||
val size = nums.size | ||
return nums.fold((size + 1) * size / 2) { acc , i -> acc - i } | ||
} | ||
|
||
@Test | ||
fun `입력받은 정수 배열에서 비어있는 정수를 반환한다`() { | ||
missingNumber(intArrayOf(3,2,1)) shouldBe 0 | ||
missingNumber(intArrayOf(3,0,1)) shouldBe 2 | ||
missingNumber(intArrayOf(9,6,4,2,3,5,7,0,1)) shouldBe 8 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package leetcode_study | ||
|
||
import io.kotest.matchers.shouldBe | ||
import org.junit.jupiter.api.Test | ||
|
||
class `valid-palindrome` { | ||
|
||
/** | ||
* 입력받은 문자열의 양 끝부터 투 포인터를 이용하여 비교한다. | ||
* TC: O(n), SC: O(1) | ||
*/ | ||
fun isPalindrome(s: String): Boolean { | ||
var (left, right) = 0 to s.length - 1 | ||
while (left < right) { | ||
while (left < right && !isAlphabetOrDigit(s[left])) { | ||
left++ | ||
} | ||
while (left < right && !isAlphabetOrDigit(s[right])) { | ||
right-- | ||
} | ||
if (s[left].lowercaseChar() != s[right].lowercaseChar()) { | ||
return false | ||
} | ||
left++ | ||
right-- | ||
} | ||
return true | ||
} | ||
|
||
private fun isAlphabetOrDigit(c: Char): Boolean = c.isDigit() || (c in 'a' .. 'z') || (c in 'A' .. 'Z') | ||
|
||
@Test | ||
fun `입력받은 문자열의 영숫자가 팰린드롬 여부를 반환한다`() { | ||
isPalindrome("A man, a plan, a canal: Panama") shouldBe true | ||
isPalindrome("race a car") shouldBe false | ||
isPalindrome("ㅁaㄹㅁb듐노+_c$#&$%#b*&@!!@a$") shouldBe true | ||
} | ||
|
||
@Test | ||
fun `입력받은 문자열이 공백만 존재한다면 참을 반환한다`() { | ||
isPalindrome(" ") shouldBe true | ||
isPalindrome(" ") shouldBe true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package leetcode_study | ||
|
||
import io.kotest.matchers.shouldBe | ||
import leetcode_study.`word-search`.Position.Companion.MOVES | ||
import org.junit.jupiter.api.Test | ||
|
||
class `word-search` { | ||
|
||
/** | ||
* 격자에 존재하는 문자를 사용하여 word 를 만들 수 있는지 확인하기 위해 DFS를 통한 visited 배열 백트래킹을 사용하여 해결 | ||
* TC: O(너비 * 높이 * 4^word), SC: O(너비 * 높이 * 4^word) | ||
*/ | ||
fun exist(board: Array<CharArray>, word: String): Boolean { | ||
return usingBacktracking(board, word) | ||
} | ||
|
||
private fun usingBacktracking(board: Array<CharArray>, word: String): Boolean { | ||
fun dfs(board: Array<CharArray>, visited: Array<BooleanArray>, word: String, position: Position, index: Int): Boolean { | ||
if (index == word.length) return true | ||
for (move in MOVES) { | ||
val next = position + move | ||
if (next.isNotOutOfIndexed(board) && !visited[next.x][next.y] && board[next.x][next.y] == word[index]) { | ||
visited[next.x][next.y] = true | ||
if (dfs(board, visited, word, next, index + 1)) return true | ||
visited[next.x][next.y] = false | ||
} | ||
} | ||
return false | ||
} | ||
|
||
val visited = Array(board.size) { | ||
BooleanArray(board[0].size) | ||
} | ||
|
||
for (x in board.indices) { | ||
for (y in board[x].indices) { | ||
visited[x][y] = true | ||
if (board[x][y] == word[0] && dfs(board, visited, word, Position(x,y), 1)) { | ||
return true | ||
} | ||
visited[x][y] = false | ||
} | ||
} | ||
return false | ||
} | ||
|
||
@Test | ||
fun `문자로 구성된 2차원 배열에서 word 문자열 존재 유무를 반환한다`() { | ||
exist(arrayOf( | ||
charArrayOf('A','B','C','E'), | ||
charArrayOf('S','F','C','S'), | ||
charArrayOf('A','D','E','E') | ||
), "ABCCED") shouldBe true | ||
exist(arrayOf( | ||
charArrayOf('A','B','C','E'), | ||
charArrayOf('S','F','C','S'), | ||
charArrayOf('A','D','E','E') | ||
), "SEE") shouldBe true | ||
exist(arrayOf( | ||
charArrayOf('A','B','C','E'), | ||
charArrayOf('S','F','C','S'), | ||
charArrayOf('A','D','E','E') | ||
), "SES") shouldBe false | ||
exist(arrayOf( | ||
charArrayOf('A','B','C','E'), | ||
charArrayOf('S','F','E','S'), | ||
charArrayOf('A','D','E','E') | ||
), "ABCESEEEFS") shouldBe true | ||
exist(arrayOf( | ||
charArrayOf('C','A','A'), | ||
charArrayOf('A','A','A'), | ||
charArrayOf('B','C','D') | ||
), "AAB") shouldBe true | ||
} | ||
|
||
data class Position( | ||
val x: Int, | ||
val y: Int | ||
) { | ||
|
||
operator fun plus(other: Position) = Position(this.x + other.x, this.y + other.y) | ||
|
||
fun isNotOutOfIndexed(board: Array<CharArray>) = | ||
this.x < board.size && this.x >= 0 && this.y < board[0].size && this.y >= 0 | ||
|
||
companion object { | ||
val MOVES: List<Position> = listOf( | ||
Position(-1, 0), | ||
Position(0, 1), | ||
Position(1, 0), | ||
Position(0, -1), | ||
) | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오! 이렇게 접근하는 방법이 있군요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
달래님 풀이를 참고했습니다 ㅎㅎ