https://school.programmers.co.kr/learn/courses/30/lessons/17679
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
전에 풀었던 뿌요뿌요와 비슷한 문제! 여기선 겹칠 수 있기 때문에 조금 다르게 구현해야 했다.
일단 전체적인 흐름은 두 가지고 나뉜다.
1. 2x2 블록 없애기
2. 밑으로 내리기
2x2를 찾아내기 위해 사용한 건 visited 부울 2차원 배열이다. 여기서 사라질 애들은 true로 변경해 준다.
겹치는 애들이 있기 때문에 여기서 "."(빈공간)로 변경하면 적절한 답이 나오지 않는다.
while문을 돌다가 사라진 블록이 없다면 바로 끝내도록 break 조건문을 걸어줬다.
그 후에 사라진 애들의 값을 "."로 바꿔줬다. 사실 따로 하지 않고 밑으로 내릴 때 하려고 했는데 헷갈려서 그냥 따로 해줬다.
(구현 시간 오래걸릴까봐 과감하게 따로 빼버렸다. 실행 시 시간초과 나오면.. 같이해야지 뭐..^^)
그 후, 밑으로 내리는 코드를 구현했다. 열마다 원소를 밑으로 내리는 코드를 구현해준다.
밑에서부터(m-2) 가장 위까지 올라가면서 "." 와 swap 해줬다.
이 부분은 꽤 헷갈리므로 다시 정리해 보겠다.
for j in 0..<n { //열마다
for i in (0..<m-1).reversed() {
var index = i
while index < m - 1, blocks[index+1][j] == "." {
let tmp = blocks[index+1][j]
blocks[index+1][j] = blocks[index][j] //swap
blocks[index][j] = tmp
index += 1
}
}
}
밑에서부터 올라가며 진행.
index에 현재 바라보고 있는 원소의 행값을 넣었다. 그리고 index는 밑으로 내려가면서 바라보고 있는 원소 밑에 "."가 있는지 체크해 줬다.
당연히 여기서 범위를 벗어나면 안 되므로 m-1보다 작아야 한다. (index는 i보다 큼) 밑 원소가 "."이라면 swap
그리고 더 밑으로도 갈 수 있으므로 index += 1
예제) m = 4, i = 2고 밑 원소들이 모두 "."인 경우
index = 2에서 시작해서 밑(index+1 = 3)과 바꿈. index = 3 이면 m - 1과 동일하므로 종료
index + 1의 값을 확인하기 때문이다!! 3 + 1(인덱스)는 out of index range!
[내 코드]
func solution(_ m:Int, _ n:Int, _ board:[String]) -> Int {
var answer = 0
var blocks = [[String]]()
var visited = [[Bool]]()
var isExploded = false
board.forEach { blocks.append($0.map{ String($0) }) }
while true {
isExploded = false
//2x2 터트리기
visited = [[Bool]](repeating: [Bool](repeating: false, count: n), count: m)
for i in 0..<m-1 {
for j in 0..<n-1 {
if blocks[i][j] == "." { continue }
if blocks[i][j] == blocks[i+1][j], blocks[i+1][j] == blocks[i][j+1],
blocks[i][j+1] == blocks[i+1][j+1] {
isExploded = true
if !visited[i][j] {
answer += 1
visited[i][j] = true
}
if !visited[i][j+1] {
answer += 1
visited[i][j+1] = true
}
if !visited[i+1][j] {
answer += 1
visited[i+1][j] = true
}
if !visited[i+1][j+1] {
answer += 1
visited[i+1][j+1] = true
}
}
}
}
if !isExploded { break } //더이상 터지지 않으면 바로 끝
for i in 0..<m {
for j in 0..<n {
if visited[i][j] {
blocks[i][j] = "."
}
}
}
//밑으로 내리기
for j in 0..<n { //열마다
for i in (0..<m-1).reversed() {
var index = i
while index < m - 1, blocks[index+1][j] == "." {
let tmp = blocks[index+1][j]
blocks[index+1][j] = blocks[index][j] //swap
blocks[index][j] = tmp
index += 1
}
}
}
}
return answer
}
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[프로그래머스/Swift] 개인정보 수집 유효기간 (0) | 2023.01.07 |
---|---|
[프로그래머스/Swift] 방문 길이 (0) | 2023.01.06 |
[프로그래머스/Swift] 오픈채팅방 (0) | 2023.01.05 |
[프로그래머스/Swift] 주차 요금 계산 (0) | 2023.01.04 |
[프로그래머스/Swift] 뉴스 클러스터링 (0) | 2023.01.04 |