[코딩 테스트 RUN] 코딩 기초 트레이닝 25일차: 완주

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

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

 

완주했다.

이제부터는 다른 코딩 테스트와 함께한다. 수업에서 SWEA 등을 배우고 있다.

 

정수를 나선형으로 배치하기

양의 정수 n이 매개변수로 주어집니다. n × n 배열에 1부터 n2 까지 정수를 인덱스 [0][0]부터 시계방향 나선형으로 배치한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.

 

문제 해설

이른바 달팽이 배열 문제라고 한다. 방법을 배우기 전에 풀었던 것은 이것.

 

class Solution {
    public int[][] solution(int n) {
        int[][] answer = {};
        answer = new int[n][n];
        int k = 0;
        int idx = 1;

        while(true) {      
            
            if(idx > n * n) break;
            
            for(int j = k; j < (n - k); j++) {
                answer[k][j] = idx;
                idx++;
            }

            for(int i = k + 1; i < n - k; i++) {
                answer[i][n - 1 - k] = idx;
                idx++;
            }
            
            if (n - 2 * k == 1) {
                k++;
                continue;
            }            

            for(int j = n - 2 - k; j >= k; j--){
                answer[n - 1 - k][j] = idx;
                idx++;
            }

            for(int i = n - 2 - k; i > k; i--) {
                answer[i][k] = idx;
                idx++;
            }
            
            k++;            
        }
        
        return answer;
    }
}

 

 

정답

이게 바로 수업에서 배운 방식이다.

class Solution {
    public int[][] solution(int n) {
        int[][] answer = {};
        answer = new int[n][n];
        int k = 0;
        int idx = 1;
        int top = 0, bottom = n - 1;
        int left = 0, right = n - 1;
        
        while(top <= bottom && left <= right){
            for(int c = left; c<= right; c++) { answer[top][c] = idx; idx++; }
            top++;
            for(int r = top; r <= bottom; r++) { answer[r][right] = idx; idx++; }
            right--;
            for(int c = right; c >= left; c--) { answer[bottom][c] = idx; idx++; }
            bottom--;
            for(int r = bottom; r >= top; r--) { answer[r][left] = idx; idx++; }
            left++;
            
        }            
                
        return answer;
    }
}

 

상하좌우를 줄여가면서 채우는 형태가 된다.

 

그런데 이런 정답이 있었다.

 

class Solution {
    public int[][] solution(int n) {
        int[][] answer = new int[n][n];
        int num = 1;
        int x = 0, y = 0;
        int dx[] = {0, 1, 0, -1};
        int dy[] = {1, 0, -1, 0};
        int direction = 0;

        while (num <= n * n) {
            answer[x][y] = num++;

            int nx = x + dx[direction]; 
            int ny = y + dy[direction];

            if (nx < 0 || nx >= n || ny < 0 || ny >= n || answer[nx][ny] != 0) {
                direction = (direction + 1) % 4; //범위 밖에 나갔을 때 방향전환
                nx = x + dx[direction];
                ny = y + dy[direction];
            }
            x = nx;
            y = ny;
        }

        return answer;
    }
}

 

즉, direction이라는 걸 설정해서 x와 y를 정하는 것.

자세히 보면 다음과 같다.

dx의 방향(첫번째는 없음, 두번째는 진행, 세번째는 없음, 네번째는 후퇴), dy의 방향(첫번째는 진행, 두번째는 없음, 세번째는 후퇴, 네번째는 없음).

이 이후에 while문으로 n * n까지의 제한을 건다.

answer[x][y]는 num++를 받는다. 그리고 nx와 ny라는 값이 생기는데, 이것이 바로 방향전환의 조건이 된다. 경계선 기준을 자세히 살펴보면, nx가 0 미만이 되거나, nx가 n이상이 되거나, ny… 등등의 조건이 있다.

이 경우 범위 밖(경계 밖)이 되어, direction이 수정된다. 그리고 nx는 x + dx[direction]이 되는데, 현재 x와 y의 방향에 dx[direction], dy[direction]을 추가해서 바꾸는 것이다. 그렇게해서 nx와 ny로 x와 y가 업데이트된다. 만약 경계가 아니면 계속 꾸준히 업데이트 되는 것.

 


특별한 이차원 배열 2

n × n 크기의 이차원 배열 arr이 매개변수로 주어질 때, arr이 다음을 만족하면 1을 아니라면 0을 return 하는 solution 함수를 작성해 주세요.

0 ≤ i, j < n인 정수 i, j에 대하여 arr[i][j] = arr[j][i]

 

 

문제 해설

그냥 말 그대로 해주면 된다. 여태까지 잘 해왔다면 쉬운 문제.

 

정답

class Solution {
    public int solution(int[][] arr) {
        for(int i = 0; i < arr.length; i++){
            for(int j = 0; j < arr.length; j++){
                if(arr[i][j] != arr[j][i]){
                    return 0;
                }
            }
        }
        
        return 1;
    }
}

 


정사각형으로 만들기

이차원 정수 배열 arr이 매개변수로 주어집니다. arr의 행의 수가 더 많다면 열의 수가 행의 수와 같아지도록 각 행의 끝에 0을 추가하고, 열의 수가 더 많다면 행의 수가 열의 수와 같아지도록 각 열의 끝에 0을 추가한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.

 

문제 해설

배열은 늘릴 수 없다. 따라서 새 배열을 만들되, if문에 따라 배열을 늘린 뒤 이후에 2중 for문으로 채워주면 된다.

 

정답

import java.util.*;

class Solution {
    public int[][] solution(int[][] arr) {
        int[][] answer = {};
        if(arr.length > arr[0].length) {
            answer = new int[arr.length][arr.length];
        } else {
            answer = new int[arr[0].length][arr[0].length];         
        }
        
        for(int i = 0; i < arr.length; i++){
            for(int j = 0; j < arr[i].length; j++){
                answer[i][j] = arr[i][j];
            }
        }
        
        return answer;
    }
}



이걸 좀 더 괜찮게 하는 방법이 있다.

 

class Solution {
    public int[][] solution(int[][] arr) {
        int max = Math.max(arr.length, arr[0].length);
        int[][] answer = new int[max][max];

        for (int i = 0; i < arr.length; i++) {
            System.arraycopy(arr[i], 0, answer[i], 0, arr[i].length);
        }

        return answer;
    }
}

 

Math.max를 사용, System.arraycopy로 복사한다.

 

System.arraycopy()

인자는 원본배열, 복사 시작 시점, 복사할 배열, 복사할 배열의 시작 시점, 복사 요소 개수이다.

2중 for문이 아니라 첫 배열의 안을 이런식으로 복사한 것.

 


이차원 배열 대각선 순회하기

2차원 정수 배열 board와 정수 k가 주어집니다.

i + j <= k를 만족하는 모든 (i, j)에 대한 board[i][j]의 합을 return 하는 solution 함수를 완성해 주세요.

 

문제 해설

그냥 2중 for문해서 i + j 확인하여 answer에 추가해주면 된다.

 

정답

class Solution {
    public int solution(int[][] board, int k) {
        int answer = 0;
        for(int i = 0; i < board.length; i++){
            for(int j = 0; j < board[i].length; j++){
                if((i + j) <= k){
                    answer += board[i][j];
                }
            }
        }
        return answer;
    }
}