[코딩 테스트 RUN] 코딩 기초 트레이닝 6일차

코테런/코딩 기초 트레이닝(완주)
2026.02.11

⚠️ 주의!
프로그래머스에서 낸 코딩 문제에 대한 해답이 들어있습니다.
열람 시 주의해주세요.

 

 

6일차 코테런. 슬슬 실수를 하거나 잘 안 되는 일이 잦아졌다. 오답노트도 써본다.

 

마지막 두 원소

정수 리스트 num_list가 주어질 때, 마지막 원소가 그전 원소보다 크면 마지막 원소에서 그전 원소를 뺀 값을 마지막 원소가 그전 원소보다 크지 않다면 마지막 원소를 두 배한 값을 추가하여 return하도록 solution 함수를 완성해주세요.

 

문제 코드

class Solution {
    public int[] solution(int[] num_list) {
        int[] answer = {};
        return answer;
    }
}

 

문제 해설

리스트에서 마지막 항목과 마지막 전 항목이 뭔지 이해할 수 있느냐를 보는 것이다.

일반적으로 마지막 항목은 Array[Array.length-1]로 꼽을 수 있다. 그 전 항목의 경우 그보다 전이므로 Array[Array.length-2]가 된다.

 

정답

class Solution {
    public int[] solution(int[] num_list) {
        int l = num_list.length;        
        int[] answer = new int[l + 1];
        int lb = l - 1;
        int last = 0;
        if(num_list[lb] > num_list[lb-1])
            last = num_list[lb] - num_list[lb-1];
        else
            last = num_list[lb] * 2;
        
        for(int i = 0; i < l; i++){
            answer[i] = num_list[i];
        }
            answer[l] = last;
        
        return answer;
    }
}

 

대부분 다 비슷하게 작성되며, 축약형태로 제출되는 경우도 많다.

프로그래머스에서 제일 많이 제출된 축약형태는 다음이다(삼항 연산자 이용).

 

class Solution {
    public int[] solution(int[] num_list) {
        int[] answer = new int[num_list.length+1];

        for(int i=0; i<num_list.length; i++){
            answer[i] = num_list[i];
        }

        answer[num_list.length] = num_list[num_list.length-1] > num_list[num_list.length-2] ? num_list[num_list.length-1]-num_list[num_list.length-2]:num_list[num_list.length-1]*2;
        return answer;
    }
}

 

수 조작하기 1

정수 n과 문자열 control이 주어집니다. control은 "w", "a", "s", "d"의 4개의 문자로 이루어져 있으며, control의 앞에서부터 순서대로 문자에 따라 n의 값을 바꿉니다.

"w" : n이 1 커집니다.
"s" : n이 1 작아집니다.
"d" : n이 10 커집니다.
"a" : n이 10 작아집니다.
위 규칙에 따라 n을 바꿨을 때 가장 마지막에 나오는 n의 값을 return 하는 solution 함수를 완성해 주세요.

 

문제 코드

class Solution {
    public int solution(int n, String control) {
        int answer = 0;
        return answer;
    }
}

 

 

문제 해설

이전과 비슷하지만 if가 아니라 제어문 switch를 사용하면 간단하다. switch의 경우 한 필드의 값에 대해 case에 따라서 스크립트를 출력한다.

따라서 case 'w'일 경우 answer += 1; break; 형태로 사용하면 된다.

 

덧붙여 한 번 오답이 났는데, 이것은 answer을 0으로 처리했기 때문이다…

제출하기 전에 테스트케이스를 처리해보는 걸 잊지 말자.

 

정답

class Solution {
    public int solution(int n, String control) {
        int answer = n;
        int num = control.length();
        char a;
        
        for(int i = 0; i<num; i++){
            a = control.charAt(i);
            
            switch(a){
                case 'w' : answer += 1; break;
                case 's' : answer -= 1; break;
                case 'd' : answer += 10; break;
                case 'a' : answer -= 10; break;
                default : answer = answer;
              }
        }
                    
        return answer;
    }
}

 

 

수 조작하기 2

정수 배열 numLog가 주어집니다. 처음에 numLog[0]에서 부터 시작해 "w", "a", "s", "d"로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다고 합시다.

"w" : 수에 1을 더한다.
"s" : 수에 1을 뺀다.
"d" : 수에 10을 더한다.
"a" : 수에 10을 뺀다.
그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog입니다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있습니다.

주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 함수를 완성해 주세요.

 

 

문제 코드

class Solution {
    public String solution(int[] numLog) {
        String answer = "";
        return answer;
    }
}

 

문제 해설

수 조작하기 1에서 아예 거꾸로가 된 것이다. 똑같이 case를 쓰면 된다. 다만 덧셈 뺄셈에 대한 역연산이 필요하므로, 현재 수에서 이전 수를 뺀 차이값으로(1, -1, 10, -10) case를 처리한다. 주의할 것은 이 경우 i = 1이어야 i -1로 같이 연산이 가능하다는 지점이다.

 

정답

class Solution {
    public String solution(int[] numLog) {
        String answer = "";
        int m;
        
        for(int i = 1; i< numLog.length; i++){
            m = numLog[i] - numLog[i - 1];
            switch(m)
            {
                case 1 : answer += "w"; break;
                case -1 : answer += "s"; break;
                case 10 : answer += "d"; break;
                case -10 : answer += "a"; break;
                default : answer = answer;
            }
        }
        
        return answer;
    }
}

 

 

수열과 구간 쿼리 3

정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. queries의 원소는 각각 하나의 query를 나타내며, [i, j] 꼴입니다.
각 query마다 순서대로 arr[i]의 값과 arr[j]의 값을 서로 바꿉니다.
위 규칙에 따라 queries를 처리한 이후의 arr를 return 하는 solution 함수를 완성해 주세요.

 

문제 코드

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        int[] answer = {};
        return answer;
    }
}

 

 

문제 해설

이중 배열에 대해서 이해할 수 있느냐를 보는 문제. 이중 배열의 경우 바깥배열이 있으며 안쪽 배열이 있는데, 이 경우 i와 j의 for문을 사용해서 순회한다.

queries의 이중배열은 둘이 서로 바뀌는 형태이므로 0과 1로 처리가 가능함에 유의할 것.

 

 

정답

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        int queryI, queryJ;
        int a, b;
        
        for(int i = 0; i < queries.length; i++){
            //둘이 서로 바뀌는 형태이기 때문에 queries의 이중배열은 2개만 존재한다
            queryI = queries[i][0];
            queryJ = queries[i][1];
            
            a = arr[queryI];
            b = arr[queryJ];
            
            arr[queryJ] = a;
            arr[queryI] = b;                        
        }
        
        return arr;
    }
}

 

 

가장 많이 제출된 답은

array 순환을 간단하게 하고, answer을 arr에서 copyOf로 복사했다.

import java.util.Arrays;

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        int[] answer = Arrays.copyOf(arr, arr.length);

        for (int[] query : queries) {
            int i = query[0];
            int j = query[1];

            int temp = answer[i];
            answer[i] = answer[j];
            answer[j] = temp;
        }

        return answer;
    }
}

 

수열과 구간 쿼리 2

정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. queries의 원소는 각각 하나의 query를 나타내며, [s, e, k] 꼴입니다.

각 query마다 순서대로 s ≤ i ≤ e인 모든 i에 대해 k보다 크면서 가장 작은 arr[i]를 찾습니다.

각 쿼리의 순서에 맞게 답을 저장한 배열을 반환하는 solution 함수를 완성해 주세요.
단, 특정 쿼리의 답이 존재하지 않으면 -1을 저장합니다.

 

문제 코드

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        int[] answer = {};
        return answer;
    }
}

 

 

문제 해설

좀 복잡하다. 일단 순회할 것은 2차원 배열쪽이다. 왜냐하면 반복이 해당 query마다가 되기 때문이다.

그리고 sek를 각각 [0], [1], [2]로 하고 지정한다.

이 경우 안을 다시 순환해야하는데(문제에서의 i 값이 s와 e사이이기 때문이다.) 그러므로 j를 s에서 시작하여 e까지 되도록 순회시키고, k보다 클경우 min값을 비교하여 min값을 추가하면 된다.

min값의 기본은 -1로 해두었다.

 


문제 풀이 과정

이번 문제는 풀이 과정에 오류가 좀 있어 오답노트를 작성한다.

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        int[] answer = new int[queries.length];
        int[] newQuery = {};
        int s, e, k;
        int min;
        
        for(int i = 0; i<queries.length; i++){
            s = queries[i][0];
            e = queries[i][1];
            k = queries[i][2];

            newQuery = new int[e - s];            
            
            for (int j = s; i < newQuery.length; j++){
                if(arr[j] > k){
                    newQuery[i] = arr[j];
                    min = newQuery[0];
                    if(min > arr[j])
                        min = arr[j];
                } else {
                    min = -1;
                }                        
                
            }
            answer[i] = min;
        }
        return answer;
    }
}

 

newQuery로 괜히 복잡하게 만든 케이스다. s와 e사이에 있는 쿼리를 잘라서 새 배열을 생성하고, 그 가운데에서 값을 찾으려고 했다. 이 때문에 아래에 int j = s; j < newQuery.length로 처리했다(i는 오타). 다만 이 경우도 문제가 있는 것이, s에서 시작하면서 newQuery.length까지인데 이 부분은 e와 맞지 않는다. 또한 newQuery.length의 길이는 사실상 new int[e - s +1] 이어야 한다. 그리고 newQuery[i] = arr[j]에서 인덱스도 i(쿼리 번호)가 아니라 j - s(구간 내 위치)여야 돌아간다. 만약 이 조건을 다 완성한다고 해도 newQuery를 사용하면 너무 많은 연산 처리가 되어 로직이 복잡해진다.

따라서 굳이 새 배열을 만들지 않고 처리하여도 안에 있는 배열을 s와 e 사이로 처리하는 쪽이 더 간단하다고 할 수 있다.

 

 

정답

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        int[] answer = new int[queries.length];
        int s, e, k;
        int min;
        
        for(int i = 0; i<queries.length; i++){
            s = queries[i][0];
            e = queries[i][1];
            k = queries[i][2];
            min = -1;
                        
            for (int j = s; j <= e; j++){
                if(arr[j] > k){
                    if(min == -1 || min > arr[j])
                        min = arr[j];
                }                                    
            }
            answer[i] = min;
        }
        return answer;
    }
}

 

 

제일 많이 제출되는 답은 이것이다.

import java.util.Arrays;

class Solution {
    public int[] solution(int[] arr, int[][] queries) {

        int[] answer = new int[queries.length];
        Arrays.fill(answer, -1);

        for (int idx = 0; idx < queries.length; idx++) {
            int[] query = queries[idx];
            int s = query[0], e = query[1], k = query[2];

            for (int i = s; i <= e; i++) {
                if (k < arr[i]) {
                    answer[idx] = answer[idx] == -1 ? arr[i] : Math.min(answer[idx], arr[i]);
                }
            }

        }

        return answer;
    }
}

 

Arrays.fill(채울 배열, 채우기 요소)

자바에서 배열을 사용할때 for문을 이용하지 않고 전부 기본값을 채우고 싶을 때 사용한다.

여기서는 -1을 채워서 기본으로 -1을 사용했다.

 

그리고 여기서는 삼항연산자와 함께 Math.min()을 사용하여 둘을 비교했다.