1861. Rotating the Box
문제 설명
- 박스가 주어지고, 공백, 돌, 보석 이렇게 세가지 경우가 있다.
- 박스가 사진처럼 90도로 회전시켜서 중력 적용한다
- 돌맹이가 있으면 더 안떨어진다.
문제 접근
- 90도로 회전하는걸보니까 회전했을때 행(첫째줄)은 -> 열의 최대값 - 현재행이 된다.
- (0,0) ,(0,1), (0,2), (0,3)일때 이게 (0,1),(1,1), (2,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([["#", ".", "*", "."],
["#", "#", "*", "."]])
[["#", "#"], ["#", "."], ["*", "*"], [".", "."]]
[#]
[.]
[#]
[.]
.으로떨어지고 #에 막힌상태로 다 아래로 끌어올려지는게 자연스러운 흐름이 아니라서 아래서부터 .위치로 땡겨준다. 생각을 하면 될 것 같았다.
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]
이런식으로 이미 있는 형태에서 그냥 가로로 땡겨주는 것을 택했다.
진짜 굳이 정말 세로 형태로 만들어줄 필요가 없었던 것 같기도, 정말 간단하게 생각할 수 있는 능력이 필요한 것 같다.