프로그래머스 Lv2. 행렬 테두리 회전하기 (Java / Python)

eora21·2022년 9월 5일
0

프로그래머스

목록 보기
14/38

문제 링크

문제 간단 해석

배열을 회전시키며 최솟값을 기록하는 문제.

Java

풀이 코드

class Solution {
    public int[] solution(int rows, int columns, int[][] queries) {
        int[][] field = new int[rows][columns];
        int y1, x1, y2, x2, before, temp, y, x, to, min;
        int[] dy = {0, 1, 0, -1};
        int[] dx = {1, 0, -1, 0};
        int[] answer = new int[queries.length];
        
        for (int i = 0; i < rows; i++)
            for (int j = 0; j< columns; j++)
                field[i][j] = columns * i + j + 1;
        
        for (int i = 0; i < queries.length; i++) {
            y1 = queries[i][0] - 1;
            x1 = queries[i][1] - 1;
            y2 = queries[i][2] - 1;
            x2 = queries[i][3] - 1;
            
            before = field[y1+1][x1];
            min = before;
            y = y1;
            x = x1;
            to = 0;
            
            while (!(y == y1 && x == x1 && to == 3)) {
                temp = field[y][x];
                field[y][x] = before;
                before = temp;
                min = Math.min(before, min);
                
                y += dy[to];
                x += dx[to];
                
                if ((y == y1 && x == x2) || (y == y2 && x == x2) || (y == y2 && x == x1))
                    to++;
            }
            
            answer[i] = min;
        }
        
        return answer;
    }
}

해석

int[][] field = new int[rows][columns];
int y1, x1, y2, x2, before, temp, y, x, to, min;
int[] dy = {0, 1, 0, -1};
int[] dx = {1, 0, -1, 0};
int[] answer = new int[queries.length];

배열을 들고 있을 field와 이전값인 before, 값 교환을 위한 temp, 방향성을 지정할 to, y와 x의 방향성인 dy, dx 등을 선언했다.

for (int i = 0; i < rows; i++)
    for (int j = 0; j< columns; j++)
        field[i][j] = columns * i + j + 1;

배열 내 값 초기화.

for (int i = 0; i < queries.length; i++) {
    y1 = queries[i][0] - 1;
    x1 = queries[i][1] - 1;
    y2 = queries[i][2] - 1;
    x2 = queries[i][3] - 1;

    before = field[y1+1][x1];
    min = before;
    y = y1;
    x = x1;
    to = 0;

    ...
}

queries에서 하나씩 가져와 값을 넣어준다. before에 (y1+1, x1) 값을 넣어준다. 이는 회전 시작 시 초기에 들어갈 값이다.
min에도 해당 값을 넣어 초기화한다.
처음에는 왼쪽->오른쪽으로 가야 하니 to를 0으로 초기화.

while (!(y == y1 && x == x1 && to == 3)) {
    temp = field[y][x];
    field[y][x] = before;
    before = temp;
    min = Math.min(before, min);

    y += dy[to];
    x += dx[to];

    if ((y == y1 && x == x2) || (y == y2 && x == x2) || (y == y2 && x == x1))
        to++;
}

answer[i] = min;

field의 현재 위치값을 가져와 temp에 저장.
현재 위치에 before에 저장해뒀던 값을 넣는다.
before에 방금 저장한 현재 위치값을 넣는다.
min에 현재 위치값과 소유값을 비교하여 최솟값을 가지고 있도록 한다.

y와 x에 방향성에 대한 값을 넣어 현재 위치를 방향성에 맞도록 진행시킨다.

만약 현재값이 방향을 회전시켜야 할 구석에 해당한다면, to를 증가시켜 다음 반복부터 다른 방향으로 진행하도록 한다.

만약 방향성이 아래 -> 위 이면서 초기 위치와 같은 곳까지 왔다면, 해당 while문을 종료시킨다.

회전이 끝났다면 지니고 있던 최솟값을 기록.

모든 회전이 끝났다면 answer를 반환한다.

Python

풀이 코드

def solution(rows, columns, queries):
    nums = []
    dy = [0, 1, 0, -1]
    dx = [1, 0, -1, 0]

    field = [[(row - 1) * (columns) + col for col in range(1, columns + 1)] for row in range(1, rows + 1)]

    for y1, x1, y2, x2 in queries:
        y, x = y1 - 1, x1 - 1
        before = field[y][x]
        min_num = rows * columns
        to = 0

        for _ in range((x2 - x1 + y2 - y1) * 2):
            if (y == y1 - 1 and x == x2 - 1) or (y == y2 - 1 and (x == x2 - 1 or x == x1 - 1)):
                to += 1
            y += dy[to]
            x += dx[to]
            before, field[y][x] = field[y][x], before
            min_num = min(field[y][x], min_num)

        nums.append(min_num)

    return nums

해석

nums = []
dy = [0, 1, 0, -1]
dx = [1, 0, -1, 0]

field = [[(row - 1) * (columns) + col for col in range(1, columns + 1)] for row in range(1, rows + 1)]

최솟값을 담을 nums와 진행방향인 dy, dx를 선언.
field를 만들며 내부 값을 초기화한다.

for y1, x1, y2, x2 in queries:
    y, x = y1 - 1, x1 - 1
    before = field[y][x]
    min_num = rows * columns
    to = 0

    for _ in range((x2 - x1 + y2 - y1) * 2):
        if (y == y1 - 1 and x == x2 - 1) or (y == y2 - 1 and (x == x2 - 1 or x == x1 - 1)):
            to += 1
        y += dy[to]
        x += dx[to]
        before, field[y][x] = field[y][x], before
        min_num = min(field[y][x], min_num)

    nums.append(min_num)

이전 값인 before와 최솟값을 유지할 min_num, 방향성인 to를 선언한다.

해당 값들을 확인할 횟수만큼 반복시키는데, 현재 지점이 방향을 꺾어야 할 구석이라면 to += 1로 방향성을 변경한다.
y와 x값에 방향성에 따른 값을 증감시키고, field 값과 before 값을 바꾼다.
min_num이 최솟값을 지니고 있을 수 있도록 유지시킨다.

회전이 끝났다면 최솟값을 nums에 추가시킨다.

그 후 최종 nums 반환.

profile
나누며 타오르는 프로그래머, 타프입니다.

0개의 댓글