프로그래머스 알고리즘 Level 1 코틀린 가장 가까운 글자

2023. 1. 22. 00:24알고리즘/문제

모든 출처는 프로그래머스에 있습니다.

https://school.programmers.co.kr/learn/courses/30/lessons/142086

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

1. 첫 번째 생각 풀이

2중 for문을 이용해서 찾는 문자의 앞문자부터 검색해서 cnt를 찾아서 list에 add 하는 방법

class Solution {
    fun solution(s: String): IntArray {
        var answer: IntArray = intArrayOf()
        val list = mutableListOf<Int>()
        for(i in s.indices) {
            var check = false
            var cnt = 0
            if(i==0){
                list.add(-1)
            } else {
                for(j in i-1 downTo 0){
                    cnt++
                    if(s[j]==s[i]){
                        list.add(cnt)
                        check = true
                        break
                    }
                }
                if(!check) list.add(-1)
            }
        }
        answer = list.toIntArray()
        return answer
    }
}

- 돌아가긴 하지만 결국 절차적 프로그래밍에서 벗어나지 못함.
for문안에 if 넣어 for문 넣고 별로 마음에 들지 않는다.
그리고 check를 만들어서 없으면 -1 들어가게 하는데 이것도 변수 또 만들기 때문에 만족스럽지 못하다.

성능면에서는 그나마 아래에 비하면 괜찮은데
찾는 char 문자가 맨 앞쪽에 가까운 곳에 있을수록 2번째 for문을 다 돌아야 한다.
끝으로 갈수록 돌아야 하는 수는 많아진다.
어쨌든 2번째 for문이 i-1부터 downTo로 내려가면서 가까운 쪽에서부터 찾기 때문에 그나마 성능은 빠르다. 흠.

2. 두 번째 코틀린 람다식 풀이

두 번째는 코틀린 람다 함수를 사용한 풀이식이다.
withIndex를 사용하면 IntValue(index: , value) 값으로 쌍을 이루는 값을 만드는데
이걸 map{ }을 이용해 i = index , c = value로 정해주고
s = "banana" 이면
0부터 i index까지 slice 한다.
그러면

이렇게 잘라서 사용한다.
그러면 비교하는 c를
slice에서 lastIndexOf(value)를 구한다.
lastIndexOf(value)를 하게 되면

마지막으로 나오는 value 값의 index를 뱉어낸다.
이때 몇 번째 떨어져 있는지 알아야 하기 때문에 현재의 i = index 값에서 lastIndexOf에서 나온 값을 빼면 인덱스 사이의 차 몇 번째 떨어져 있는지 구하게 된다.

class Solution {
    fun solution(s: String): List<Int> = s.withIndex().map { (i, c) ->
        s.slice(0 until i).lastIndexOf(c).let {
            if(it>=0) i-it else -1
        }
    }
}

성능면에서는 위와 비교했을 때 두세 배 정도로 차이가 나는데 요즘 컴퓨터나 핸드폰으로 이 정도 성능차는 상관이 없지 않을까 생각한다. 그래도 뭐 차이가 나긴 하는 걸 알 수 있다.