(Swift) Programmers 행렬 테두리 회전하기

SteadySlower·2023년 3월 16일
0

Coding Test

목록 보기
229/305

코딩테스트 연습 - 행렬 테두리 회전하기

문제 풀이 아이디어

처음에 문제를 읽었을 때는 뭔가 규칙이 있을거라고 생각을 했는데요. 하지만 테두리를 회전이 다음 회전에 영향을 미치므로 규칙을 찾는 것이 불가능합니다. 따라서 직접 행렬을 이차원 배열로 구현하고 회전해서 답을 구해보도록 하겠습니다.

회전하는 코드는 조금 복잡해보이지만 결국에는 회전 방향에 따라서 구역을 나눠서 회전시키면 됩니다. 다만 이 경우 하나의 matrix 내에서 회전을 하면 숫자의 중복이 발생할 수 있으므로 matrix를 복사해서 회전한 후 덮어 씌우는 방법을 사용했습니다. (다른 분들의 코드를 보면 matrix[r1][c1]을 별도로 저장해두고 사용하는 방법을 사용하는 경우도 있었습니다.)

코드

func solution(_ rows:Int, _ columns:Int, _ queries:[[Int]]) -> [Int] {
    // query를 받아서 회전하는 함수
    func rotate(_ query: [Int]) -> Int {
        let r1 = query[0]
        let c1 = query[1]
        let r2 = query[2]
        let c2 = query[3]

        // matrix를 복사해서 회전에 사용
        var rotated = matrix
        
        // 회전 대상의 최소값을 저장하는 함수
        var result = Int.max

        // 회전방향에 따라서 구역을 나누어서 회전
        for r in r1...r2 {
            for c in c1...c2 {
                if r == r1 && (c1 + 1)...c2 ~= c {
                    rotated[r][c] = matrix[r][c - 1]
                } else if (r1 + 1)...r2 ~= r && c == c2 {
                    rotated[r][c] = matrix[r - 1][c]
                } else if r == r2 && c1...(c2 - 1) ~= c {
                    rotated[r][c] = matrix[r][c + 1]
                } else if r1...(r2 - 1) ~= r && c == c1 {
                    rotated[r][c] = matrix[r + 1][c]
                } else {
                    continue //👉 회전하는 영역이 아닐 경우 result 갱신하지 않도록 continue
                }
                // 최소값과 비교
                result = min(rotated[r][c], result)
            }
        }

        // 회전된 내용을 원래 matrix에 덮어 씌우기
        matrix = rotated

        // 최소값 리턴
        return result
    }
    
    // query에 있는 좌표를 그래도 쓰기 위해서 rows와 columns 보다 1 큰 matrix 만들기
    var matrix = Array(repeating: Array(repeating: 0, count: columns + 1), count: rows + 1)
    // 최소값들을 저장하는 배열
    var results = [Int]()

    // matrix 채우기
    for i in 1..<(rows + 1) {
        for j in 1..<(columns + 1) {
            matrix[i][j] = j + (i - 1) * columns
        }
    }

    // 쿼리에 맞게 이동하고 최솟값을 배열에 넣기
    for query in queries {
        results.append(rotate(query))
    }

    return results
}
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글