[코딩테스트] 연습

Sdoubleu·2026년 8월 17일

프로그래머스

목록 보기
35/35
post-thumbnail

완주하지 못한 선수

  • 난이도: lv 1 / 걸린 시간: 5분
  • 내 첫 접근: for문으로 한 바퀴 돌려서 remove로 없애거나 contains로 남은 것을 반환하면 되겠다
  • 실제 사용한 자료구조/패턴: hashMap
  • 막혔던 지점:
    막혔다기보다 1차원 적인 생각으로 인해 테스트케이스가 많아지면 문제가 생길 가능성을 염두하지 못했다
  • 내 코드
fun solutionContains(participant: Array<String>, completion: Array<String>): String {
    val c = completion.toMutableList()
    for (name in participant) {
        if (!c.contains(name)) {
            return name
        }
        c.remove(name) // 이미 매칭된 원소는 지워야 동명이인 처리가 됨
    }
    return ""
}
  • 개선 코드
fun solution(participant: Array<String>, completion: Array<String>): String {
    val map = HashMap<String, Int>()

    // 1. participant 각 이름의 등장 횟수를 +1
    for (name in participant) {
        map[name] = map.getOrDefault(name, 0) + 1
    }

    // 2. completion 각 이름의 등장 횟수를 -1
    for (name in completion) {
        map[name] = map.getOrDefault(name, 0) - 1
    }

    // 3. 카운트가 0보다 크게 남은 이름 = 완주 못한 사람
    for ((name, count) in map) {
        if (count > 0) return name
    }

    return "" // 못 찾은 경우 (여기 도달하면 안 됨)
}
  • 다음에 비슷한 문제 보면 떠올릴 키워드:
    "빠르게 존재 여부/개수를 확인해야 한다", "몇 번 등장했는지 세야 한다" (빈도수 계산),
    . "A그룹과 B그룹을 비교해서 차이/교집합/합집합을 찾아야 한다",
    "정렬 없이 순서 상관없이 빠르게 처리해야 한다"

  • 해시맵이 아닌 신호:
    "순서가 중요하다" / "인덱스 위치 자체가 의미 있다" → 배열/리스트가 맞음
    "정렬된 상태를 유지해야 한다" → TreeMap이나 정렬 후 처리
    "값 하나만 저장하면 되고 개수는 필요 없다" → HashSet이 해시맵보다 더 적합 (오늘 문제도 사실 카운트까지 필요 없으면 Set으로도 풀 수 있어요, 다만 동명이인 때문에 카운트가 필요해서 HashMap을 쓴 거고요)


폰켓몬

  • 난이도: lv 1 / 걸린 시간: 10분
  • 내 첫 접근: 해시맵으로 넣은 다음에, 해시맵 사이즈를 통해서 N, N/2 값 구하고 그거를 조합을 쓰려 했다
  • 실제 사용한 자료구조/패턴: Set, min
  • 막혔던 지점:
  • 다음에 비슷한 문제 보면 떠올릴 키워드: 중복 없음
  • 코드
fun solution(nums: IntArray): Int {
    val distinctCount = nums.toSet().size   // 요인 1: 서로 다른 종류 수
    val pickLimit = nums.size / 2            // 요인 2: 고를 수 있는 최대 개수

    return minOf(distinctCount, pickLimit)   // 둘 중 더 "제한이 되는" 쪽
}

두 개 뽑아서 더하기

  • 난이도: lv 1 / 걸린 시간: 5분
  • 내 첫 접근: 이중 포문
  • 실제 사용한 자료구조/패턴: HashSet
  • 막혔던 지점:
  • 다음에 비슷한 문제 보면 떠올릴 키워드:
  • 코드
class Solution {
    fun solution(numbers: IntArray): IntArray {
        val result = mutableListOf<Int>()
        
        for (i in 0 until numbers.size) {
            for (j in i + 1 until numbers.size) {
                result.add(numbers[i] + numbers[j])
            }
        } 
        return result.toHashSet().sorted().toIntArray()
    }
}

모의고사

  • 난이도: lv 1 / 걸린 시간: 15분
  • 내 첫 접근: 포문으로 만 번 돌리려고 했다 ... 빠르게 풀기 위해선 이렇게밖에 생각을 못했다
  • 실제 사용한 자료구조/패턴: 완전 탐색
  • 막혔던 지점: 만 번을 돌리는게 맞나 ?
  • 다음에 비슷한 문제 보면 떠올릴 키워드: 반복되는 규칙
  • 코드
import kotlin.math.max
class Solution {
    fun solution(answers: IntArray): IntArray {
        var answer = intArrayOf()
        val first = intArrayOf(1,2,3,4,5)
        val second = intArrayOf(2,1,2,3,2,4,2,5)
        val third = intArrayOf(3,3,1,1,2,2,4,4,5,5)
        val ansMut = arrayListOf<Int>(0,0,0)
        var cnt = 0
        answers.forEach {
            if(it == first[cnt % first.size]) ansMut[0]++
            if(it == second[cnt % second.size]) ansMut[1]++
            if(it == third[cnt % third.size]) ansMut[2]++
            cnt++
        }
        for(i in 0..2) {
            if(ansMut.maxOrNull() == ansMut[i]) answer = answer.plus(i + 1)
        }
        
        answer.sort()
        
        return answer
    }
}

cnt % 배열.size로 순환 시키는 것을 다시 한 번 기억하자..


체육복

  • 난이도: lv 1 / 걸린 시간: 30분
  • 내 첫 접근:
var n = 5
    val mLost = mutableListOf(2,4)
    val mReserve = mutableListOf(1,3,5)
 
    for(i in mLost) {
        if(i - 1 in mReserve) {
            mReserve.remove(i-1)
            mLost.remove(i)
        } else if(i + 1 in mReserve) {
            mReserve.remove(i+1)
            mReserve.add(i)
        }
    }
  • 실제 사용한 자료구조/패턴: 그리디
  • 막혔던 지점: 잃어버린 학생의 앞뒤를 여벌로 가져온 사람을 가져오면 되겠구나?
  • 다음에 비슷한 문제 보면 떠올릴 키워드: 지문의 예외 문장 = 반드시 코드 한 단계로 분리
  • 코드
class Solution {
    fun solution(n: Int, lost: IntArray, reserve: IntArray): Int {
        var mLost = mutableListOf<Int>()
        var mReserve = mutableListOf<Int>()
        var answer = 0
        
        lost.forEach { mLost.add(it) }
        reserve.forEach { mReserve.add(it) }
        
        mLost.sort()
        
        for(i in 1..n) {
            if(i in mLost && i in mReserve) {
                mReserve.remove(i)
                mLost.remove(i)
            }
        }
        
        for (i in 1..n) {
            if (i in mLost) {
                if (i - 1 in mReserve) {
                    mReserve.remove(i - 1)
                    mLost.remove(i)
                } else if (i + 1 in mReserve) {
                    mReserve.remove(i + 1)
                    mLost.remove(i)
                }
            }
        }
        
        answer = n - mLost.size
        
        return answer
    }
}

항상 제한 사항을 주의깊게 보자 제발


K번째수

  • 난이도: lv 1 / 걸린 시간: 12분
  • 내 첫 접근: 각 commands에 접근해서 인덱스를 사용해서 넣어야겠다
  • 실제 사용한 자료구조/패턴: 배열 슬라이싱 + 정렬
  • 막혔던 지점:
  • 다음에 비슷한 문제 보면 떠올릴 키워드:
  • 코드
fun main() {
    val array = intArrayOf(1,5,2,6,3,7,4)
    val commands = arrayOf(intArrayOf(2,5,3),intArrayOf(4,4,1),intArrayOf(1,7,3))
    var mArray = mutableListOf<Int>()

    for(i in commands) {
        var list = mutableListOf<Int>()
        for(j in i[0] - 1 until  i[1]) { // 2 .. 5
            list.add(array[j])
        }
        mArray.add(list.sorted() [ i[2] - 1 ] )
    }
    println(mArray)
}

크레인 인형 뽑기

  • 난이도: lv 1 / 걸린 시간: 30분
  • 내 첫 접근: 인덱스로 순환하면서 하나씩 removeLast()를 써서 비교하기
  • 실제 사용한 자료구조/패턴: Stack
  • 막혔던 지점: 2차 배열이다보니까 인덱스 접근 방법을 실수했고, move에 있는 수로 인덱스를 접근할 때 항상 outOfIndex 에러를 항상 조심해야할 것 이다.
  • 다음에 비슷한 문제 보면 떠올릴 키워드: 쌓는다
  • 코드
class Solution {
    fun solution(board: Array<IntArray>, moves: IntArray): Int {
        var bag = mutableListOf<Int>()
        var answer = 0
        var arr = mutableListOf<MutableList<Int>>()
        for(i in board.size - 1 downTo 0) {
            val ele = mutableListOf<Int>()
            for(j in board[i]) {
                ele.add(j)
                }
                arr.add(ele)
            }
    
        for(move in moves) {
            for(i in arr.size - 1 downTo 0) {
                if(arr[i][move - 1] <= 0 ) continue
                else {
                    val last = arr[i][move - 1]
                    if(bag.isNotEmpty() && bag.last() == last) {
                        bag.removeLast()
                        answer += 2
                    } else bag.add(last)
                    arr[i][move - 1] = -1
                    break
                }
            }
        }
        
        return answer
    }
}

실패율

  • 난이도: lv 1 / 걸린 시간: 50분
  • 내 첫 접근:
  • 실제 사용한 자료구조/패턴: HashMap(스테이지 번호 → 실패율) + 리스트 변환 후 정렬
  • 막혔던 지점: 분모가 0일 때
  • 다음에 비슷한 문제 보면 떠올릴 키워드:
  • 코드
class Solution {
    fun solution(N: Int, stages: IntArray): IntArray {
        var answer = mutableMapOf<Int, Double>()
        var total = stages.size
        for(i in 1 .. N) {
            val person = stages.filter { it == i }.size
            if(person == 0) {
                answer[i] = 0.0
                continue
            }
            answer[i] = person.toDouble() / total
            total -= person
        }
        return answer.toList().sortedByDescending{ it.second }.map{ it.first }.toIntArray()
    }
}

문자열 내 마음대로 정렬하기

  • 난이도: lv 1 / 걸린 시간: 9분
  • 내 첫 접근: sortedBy{ it[n] } 를 이용해서 정렬을 해보자
  • 실제 사용한 자료구조/패턴: 다단계 안정 정렬
  • 막혔던 지점: 사전순으로 앞선 문자열을 어떻게 배치하지 ? 그냥 정렬하면 되나 ?
  • 다음에 비슷한 문제 보면 떠올릴 키워드: 인덱스를 기준으로 정렬
  • 코드
1차 코드
class Solution {
    fun solution(strings: Array<String>, n: Int): Array<String> {
        var answer = mutableListOf<String>()
        for(i in strings) answer.add(i)
        answer.sort()
        answer.sortBy { it[n] }
        return answer.toTypedArray()
    }
}


2차 코드
class Solution {
    fun solution(strings: Array<String>, n: Int): Array<String> {
        
        return strings.sorted().sortedBy { it[n] }.toTypedArray()
    }
}

로또의 최고 순위와 최저 순위

  • 난이도: lv 1 / 걸린 시간: 30분
  • 내 첫 접근:
  • 실제 사용한 자료구조/패턴: 배열순회
  • 막혔던 지점: 다 틀렸을 때 예외 처리를 어떻게 해야할 지 막혔었다
  • 다음에 비슷한 문제 보면 떠올릴 키워드:
  • 코드
class Solution {
    fun solution(lottos: IntArray, win_nums: IntArray): IntArray {
        var answer: IntArray = intArrayOf(0,0)
        var same = 0
        var zero = 0
        for(i in lottos) {
            if(win_nums.contains(i)) same++
            if(i == 0) zero++
        }
        var pride = 7 - same - zero
        // 최고 등수
        if(1 <= pride && pride <= 6) answer[0] = pride else answer[0] = 6
        // 최저 등수
        if(1 <= same && same <= 6) answer[1] = 7 - same else answer[1] = 6
        
        return answer
    }
}
profile
Android

0개의 댓글