티스토리 뷰

코드카타

 

옹알이 (2)

 

문제

 

 

정답

class Solution {
    fun solution(babbling: Array<String>): Int {
        val able = listOf("aya", "ye", "woo", "ma")
        return babbling.count { i ->
            var word = i
            for (a in able) {
                if (!word.contains(a.repeat(2))) {
                    word = word.replace(a, " ")
                }
            }
            word.all { it.isWhitespace() }
        }
    }
}

각 옹알이에서 발음할 수 있는 단어의 연속된 발음을 포함하는지의 여부를 판단해주면 된다.

 

 

발음 리스트 선언

val able = listOf("aya", "ye", "woo", "ma")

조카가 할 수 있는 4가지의 발음을 리스트에 선언한다.

 

 

발음 가능한 단어개수 구하기

babbling.count { i ->
    var word = i
    for (a in able) {
        if (!word.contains(a.repeat(2))) {
            word = word.replace(a, " ")
        }
    }
    word.all { it.isWhitespace() }
}

// word에 a가 포함된 경우 : aya -> " " 
// word에 a와 다른 단어가 포함된 경우 : yee -> " e"
// word에 연속된 단어가 포함된 경우 : yeye -> "yeye"
// word에 a가 포함되어 있지 않는 경우 : u -> "u"

word는 각 옹알이에 해당하고 해당 값을 변경해주기 위해 람다문 내에서 var로 선언해준다.

 

able 리스트를 순회하면서 word에 연속된 발음 포함되어 있는지 검사한다.

연속된 발음이 포함되어있지 않다면 word에서 a(발음 가능 단어)를 공백으로 초기화한다.

word가 a를 포함하고 있지 않다면 word는 변하지 않게 된다.

 

word의 모든 값이 공백이라면,

즉 word에서 a의 연속된 발음이 포함되어 있지 않거나 a가 포함되어 있다면

count 람다문의 조건을 만족하여서 카운트가 된다.

 

 

 

숫자 짝궁

 

문제

 

 

정답

class Solution {
    fun solution(X: String, Y: String): String {
        var pair = ""
        
        for(i in 0..9){
            val n = (i+48).toChar()
            val cntX = X.filter{it == n}.count()
            val cntY = Y.filter{it == n}.count()
            val minCnt = if(cntX >= cntY) cntY else cntX
            if(minCnt > 0) pair += n.toString().repeat(minCnt)  
        }
                
        if(pair.isEmpty()) return "-1"        
        var res = pair.toCharArray().sortedDescending().joinToString("")
        return if(res[0]=='0') "0" else res 
    }
}

개인적으로 정말 어려웠던 문제였다.

 

 

시간초과 문제 해결

for(i in 0..9){
    // X와 Y의 요소 중 같은 문자(숫자)끼리 짝지어진 문자열을 만드는 로직
}

제한 사항에서 X, Y의 길이는 최대 3,000,000이라고 알려준다.

그 때문에 X나 Y문자열을 기준으로 반복문을 돌리게 되면 시간 초과가 나게 된다.

그래서 0 ~ 9 숫자(문자)를 탐색하는 방식으로 로직을 구현하였다.

 

 

숫자를 문자로 변경

val n = (i + 48).toChar()

숫자를 문자로 변경하게 되면 아스키코드 값을 기준으로 변경하게 되는데

'0' ~ '9'는 48 ~ 57의 아스키코드 값을 가지게 된다.

 

 

두 문자열에서 같은 문자 반환

for(i in 0..9){
    val n = (i+48).toChar()
    val cntX = X.filter{it == n}.count()
    val cntY = Y.filter{it == n}.count()
    val minCnt = if(cntX >= cntY) cntY else cntX
    if(minCnt > 0) pair += n.toString().repeat(minCnt)
}

X, Y에서 0~9까지의 각 숫자의 개수를 세고 그 중 최소값을 구한다.

X, Y에서  같은 수가 존재한다면 pair에 n을 최소값만큼 반복해서 더한다.

 

 

조건에 맞게 문자열 가공

if(pair.isEmpty()) return "-1"        
var res = pair.toCharArray().sortedDescending().joinToString("")
return if(res[0]=='0') "0" else res

// X = "100", Y = ""2345" -> pair = "", res = "-1"
// X = "100", Y = ""203045" -> pair = "00", res = "0"
// X = "5525", Y = ""1255" -> pair = "255", res = "552"

pair가 2번째 케이스와 같은 값을 가질 때 0을 반환하기 위해선

res의 0번지 값이 '0'인지 확인해야 하기 때문에

먼저 pair가 공백이라면 -1을 반환하는 구문을 써준다. 

 

여기서 res[0]은 char에 해당하므로 비교값에 '(작은따옴표)를 써야한다.

반대로 String을 조건식에 넣을 땐 비교값에 "(큰따옴표)를 써야한다. 

 

res는 문자열 pair문자열을 내림차순 한 값에 해당하고,

 조건에 따라 "0" 혹은 res를 반환한다.

 

 

 

체육복

 

문제

 

 

정답

class Solution {
    fun solution(n: Int, lost: IntArray, reserve: IntArray): Int {
        
        lost.sort()
        reserve.sort()
        
        var lostSet = (lost.toSet() - reserve.toSet()).toMutableSet()
        val reserveSet = reserve.toSet() - lost.toSet()
        
        for (i in reserveSet) {
            if (i - 1 in lostSet) lostSet.remove(i - 1) else lostSet.remove(i + 1)
        }
        
        return n - lostSet.size
    }
}

체육복을 다 빌려주고 난 뒤에도 체육복이 없는 학생을 전체 학생 수에서 빼주면 된다.

 

 

두 학생의 집합 초기화

var lostSet = (lost.toSet() - reserve.toSet()).toMutableSet()
val reserveSet = reserve.toSet() - lost.toSet()

배열의 차집합을 구하는 연산을 진행하기 위해 인자값으로 주어진 배열을 Set으로 변환한다.

 

체육복을 도난당했지만 여벌의 체육복이 존재한다면 체육 수업에 참여할 수 있으므로

lostSet에는 체육복을 도난 당했고 여벌이 없는 학생들의 집합으로 초기화한다.

 

여벌 체육복을 가져온 학생이 도난을 당했다면 체육복을 빌려줄 수 없으므로 

reserveSet은 여벌 체육복이 있고 도난당하지 않은 학생들의 집합으로 초기화 한다.

 

 체육복을 도난당한 학생의 집합인 lostSet은 값의 변경이 필요하므로 자료형을 가변형 Set로 변환한다.

 

 

체육복 빌려주기

for (i in reserveSet) {
    if (i - 1 in lostSet) lostSet.remove(i - 1) else lostSet.remove(i + 1)
}

i는 여분의 체육복을 가지고 있는 학생의 번호에 해당하며

그 학생을 기준으로 i - 1 은 앞번호 i + 1 은 뒷번호에 해당한다.

 

앞번호 혹은 뒷번호가 lostSet에 포함되어 있다면 그 번호의 학생에게

체육복을 빌려줘야 하므로 lostSet에서 체육복을 빌려준 학생의 번호를 제거한다.

 

 

정렬의 필요성

lost.sort()
reserve.sort()

두 배열의 요소가 오름차순 정렬되어 주어진다는 언급이 없었기 때문에 먼저 두 배열을 정렬해줘야 한다.

 

왜냐하면 여분의 체육복을 갖고있는 학생의 번호를 기준으로 체육복을 도난당한 학생에게

체육복을 빌려주는 것이 문제를 해결하기 위해 구현해야할 로직이기 때문이다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함