코딩테스트/프로그래머스

[프로그래머스 JAVA] 181832. 정수를 나선형으로 배치하기

tkxx_ls 2024. 6. 20. 14:41

문제 링크


 

프로그래머스

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

programmers.co.kr

 

접근 방법


나선형으로 배열을 채우기 위해 오른쪽, 아래, 왼쪽, 위 4방향으로 순차적으로 채워야 합니다.

따라서 각 방향마다 출발지점을 만들고 채워줍니다.

소스 코드


class Solution {
    public int[][] solution(int n) {
        int[][] answer = new int[n][n], a = {{0, 0}, {0, n - 1}, {n - 1, n - 1}, {n - 1, 0}};
        int[] d = {0, 1, 2, 3};
        boolean flag = false;
        
        for (int i = 1; i <= n * n; ) {
            for (int j = 0; j < 4 && i <= n * n; j++) {
                if (d[j] == 0) { // 오른쪽으로 움직일 때
                    flag = false;
                    for (int k = a[0][1]; k < a[1][1]; k++) {
                        answer[a[0][0]][k] = i++;
                        flag = true;
                    }
                    if (flag) // 움직였을 때만 시작지점을 변경한다.
                        a[0][0]++; a[0][1]++;
                } else if (d[j] == 1) { // 아래로 움직일 때
                    flag = false;
                    for (int k = a[1][0]; k < a[2][0]; k++) {
                        answer[k][a[1][1]] = i++;
                        flag = true;
                    }
                    if (flag)
                        a[1][1]--; a[1][0]++;
                } else if (d[j] == 2) { // 왼쪽으로 움직일 때
                    flag = false;
                    for (int k = a[2][1]; k > a[3][1]; k--) {
                        answer[a[2][0]][k] = i++;
                        flag = true;
                    }
                    if (flag)
                        a[2][0]--; a[2][1]--;
                } else {				// 위로 움직일 때
                    flag = false;
                    for (int k = a[3][0]; k >= a[0][0]; k--) {
                        answer[k][a[3][1]] = i++;
                        flag = true;
                    }
                    if (flag)
                        a[3][0]--; a[3][1]++;
                }

            }
        }
        
        return answer;
    }
}

코드 설명


처음에 배열 각 모서리를 출발 지점으로 정했습니다.

출발 지점에서 다음 출발 지점에 도착하기 전까지 채워줍니다.

다음 출발 지점을 만나면 방향을 바꿔서 채워줍니다.

만약 채우지 않았다면 출발지점을 바꾸지 않습니다.

 

개선 코드


class Solution {
    public int[][] solution(int n) {
        int[][] answer = new int[n][n];
        int[] dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};
        int d = 0, x = 0, y = 0, i = 1;
        
        while (i <= n * n) {
            answer[y][x] = i++;
            int nx = x + dx[d], ny = y + dy[d];
            
            if (nx < 0 || nx == n || ny < 0 || ny == n || answer[ny][nx] != 0) {
                d = (d + 1) % 4;
                nx = x + dx[d];
                ny = y + dy[d];
            }
            
            y = ny;
            x = nx;
        }
        
        return answer;
    }
}