[Swift] [58일차] 1861_LEET 90도 회전

·2025년 2월 3일
0

SwiftAlgorithm

목록 보기
61/105
post-thumbnail

1861. Rotating the Box


문제 설명

  1. 박스가 주어지고, 공백, 돌, 보석 이렇게 세가지 경우가 있다.
  2. 박스가 사진처럼 90도로 회전시켜서 중력 적용한다
  3. 돌맹이가 있으면 더 안떨어진다.

문제 접근

  1. 90도로 회전하는걸보니까 회전했을때 행(첫째줄)은 -> 열의 최대값 - 현재행이 된다.
  2. (0,0) ,(0,1), (0,2), (0,3)일때 이게 (0,1),(1,1), (2,1),(3,1)이 된다는 뜻
  3. 이런식으로 일단 다 만들어주고, 아래로 떨어지는건 그때 구상을 하면 될 듯 ?

문제풀이

  1. 일단 중력요소는 무시하고 풀이를 진행했을 때
class Solution {
    func rotateTheBox(_ boxGrid: [[Character]]) -> [[Character]] {
        let maxRow = boxGrid.count
        let maxCol = boxGrid[0].count
        var grid = Array(
            repeating: Array(repeating: ".", count: maxRow),
            count: maxCol
        )

        for (row_idx, row) in boxGrid.enumerated() {
            for (idx, box) in row.enumerated() {
                grid[idx][maxRow - row_idx - 1] = String(box)
            }
        }
        print(grid)
        return [["#"]]
    }
}

Solution().rotateTheBox([["#", ".", "*", "."],
                         ["#", "#", "*", "."]])

다음과 같이 90도로 잘 회전된 것을 볼 수 있다.

[["#", "#"], ["#", "."], ["*", "*"], [".", "."]]
  1. 중력을 적용할때 아래서부터 해야될 것 같았다.
    ex) 아래 같은 상황이라면
	[#]
	[.]
	[#]
	[.]

.으로떨어지고 #에 막힌상태로 다 아래로 끌어올려지는게 자연스러운 흐름이 아니라서 아래서부터 .위치로 땡겨준다. 생각을 하면 될 것 같았다.

 for row in stride(from: grid[0].count - 1, through: 0, by: -1) {
            var emptyIdx = [Int]()
            for col in stride(from: grid.count - 1, through: 0, by: -1) {
                if grid[col][row] == "#" {
                    if !emptyIdx.isEmpty { // 이미 저장된 공백이 있다면은
                        let sup = emptyIdx.removeFirst()
                        grid[col][row] = grid[sup][row]
                        grid[sup][row] = "#"
                        emptyIdx.append(col)
                    }
                }
                else if grid[col][row] == "*" { // 벽돌만나면 초기화
                    emptyIdx = [] // 벽돌빼고 스택 다 날려주셈
                }
                else {
                    emptyIdx.append(col)
                }
            }
        }

stride활용해서 역으로 순회했고, emptyIdx라는 스택을 활용해줘서 가장 깊숙한 곳부터 채워지게끔 유도했다.

최종제출

class Solution {
    func rotateTheBox(_ boxGrid: [[Character]]) -> [[Character]] {
        let maxRow = boxGrid.count
        let maxCol = boxGrid[0].count
        var grid: [[Character]] = Array(
            repeating: Array(repeating: ".", count: maxRow),
            count: maxCol
        )

        for (row_idx, row) in boxGrid.enumerated() {
            for (idx, box) in row.enumerated() {
                grid[idx][maxRow - row_idx - 1] = box
            }
        }

        for row in stride(from: grid[0].count - 1, through: 0, by: -1) {
            var emptyIdx = [Int]()
            for col in stride(from: grid.count - 1, through: 0, by: -1) {
                if grid[col][row] == "#" {
                    if !emptyIdx.isEmpty { // 이미 저장된 공백이 있다면은
                        let sup = emptyIdx.removeFirst()
                        grid[col][row] = grid[sup][row]
                        grid[sup][row] = "#"
                        emptyIdx.append(col)
                    }
                }
                else if grid[col][row] == "*" { // 벽돌만나면 초기화
                    emptyIdx = [] // 벽돌빼고 스택 다 날려주셈
                }
                else {
                    emptyIdx.append(col)
                }
            }
        }

        return grid
    }
}

나름 최선으로 짠것같았는데, 절반정도 더 빠른 코드가 있어서 그 부분을 좀 살펴보았다.

타인의코드

class Solution {
    func rotateTheBox(_ boxGrid: [[Character]]) -> [[Character]] {
        let rows = boxGrid.count
        let col = boxGrid[0].count
        var res = Array(repeating:Array(repeating: Character("."), count: rows), count: col) 
        for r in 0..<rows {
            var i = col - 1
            for c in stride(from: col - 1, through: 0, by: -1) {
                if boxGrid[r][c] == "#" {
                    res[i][rows - r - 1] = "#"
                    i -= 1
                } else if boxGrid[r][c] == "*" {
                     res[c][rows - r - 1] = "*"
                     i = c - 1
                }
            }
        }
        return res
    }
}

이분은 나처럼 원시적으로 이걸 정말 뒤집지않고, box[r][c]로 구분을 해주되, 진짜 회전된것처럼 res[c][row-r-1] 이런식으로 이미 있는 형태에서 그냥 가로로 땡겨주는 것을 택했다.
진짜 굳이 정말 세로 형태로 만들어줄 필요가 없었던 것 같기도, 정말 간단하게 생각할 수 있는 능력이 필요한 것 같다.

profile
기억보단 기록을

0개의 댓글