https://youtu.be/6lH4nO3JfLk?si=VJAa2R-huRKNzl6O
문제 설명 요약
- 게임 보드 구조:
- n x n 크기의 정수 행렬 board가 있습니다.
- board는 Boustrophedon 스타일로 채워져 있습니다:
- 숫자는 아래 왼쪽에서 시작하여 첫 줄은 왼쪽 → 오른쪽으로 채워지고,
- 다음 줄은 오른쪽 → 왼쪽으로 채워지는 식으로 반복됩니다.
- 각 칸은 1부터 n2까지의 숫자로 라벨링됩니다.
- 초기 상태:
- 게임은 1번 칸(왼쪽 아래)에서 시작합니다.
- 이동 규칙:
- 매 턴마다 주사위를 굴려 1에서 6 사이의 값을 얻습니다.
- 현재 칸 curr에서 [curr + 1, min(curr + 6, n^2)] 범위 내의 칸 중 하나로 이동합니다.
- 예: 현재 칸이 10이면, 다음 칸은 11에서 16 사이입니다.
- 이동한 칸에 사다리 또는 뱀이 있으면 해당 칸의 목적지로 즉시 이동합니다.
- 예: 칸 12에 사다리가 있고, 사다리 목적지가 20이라면 20으로 이동.
- 목표:
- n2 번 칸(오른쪽 위)으로 이동하는 데 필요한 최소 주사위 굴림 횟수를 계산합니다.
- 만약 n2 번 칸에 도달할 수 없다면 -1을 반환합니다.
from collections import deque
from typing import List
class Solution:
def snakesAndLadders(self, board: List[List[int]]) -> int:
length = len(board) # 보드의 크기(n x n)에서 n을 가져옴
"""
board는 일반적으로 행렬 형태로 저장
하지만 문제에서 언급된 Boustrophedon 스타일에서는:
숫자가 아래쪽부터 시작하여 위로 올라가면서 채워지고,
각 행에서 왼쪽에서 오른쪽, 오른쪽에서 왼쪽으로 번갈아가며 채워짐
일반 행렬의 형태:
[ [36, 35, 34, 33, 32, 31], # row 0
[25, 26, 27, 28, 29, 30], # row 1
[24, 23, 22, 21, 20, 19], # row 2
[13, 14, 15, 16, 17, 18], # row 3
[12, 11, 10, 9, 8, 7], # row 4
[ 1, 2, 3, 4, 5, 6]] # row 5
board.reverse()를 통해 마지막 row가 가장 위로 오게 변환
[ [ 1, 2, 3, 4, 5, 6], # row 0
[12, 11, 10, 9, 8, 7], # row 1
[13, 14, 15, 16, 17, 18], # row 2
[24, 23, 22, 21, 20, 19], # row 3
[25, 26, 27, 28, 29, 30], # row 4
[36, 35, 34, 33, 32, 31]] # row 5
"""
board.reverse() # Boustrophedon 스타일과 맞추기 위해 보드의 순서를 뒤집음
def inToPos(square):
"""
Boustrophedon 스타일에서 주어진 숫자(square)를 행렬 좌표 [r, c]로 변환
예를 들어:
r
5: 36 35 34 33 32 31
4: 25 26 27 28 29 30
3: 24 23 22 21 20 19
2: 13 14 15 16 17 18
1: 12 11 10 9 8 7
0: 1 2 3 4 5 6
--------------------
c 0 1 2 3 4 5
square가 1부터 시작하므로 이를 0 기반 인덱스로 변환
"""
r = (square-1) // length # square가 몇 번째 행(r)에 있는지 계산
c = (square-1) % length # square가 몇 번째 열(c)에 있는지 계산
if r % 2: # r이 홀수(1, 3, ...)라면 오른쪽 -> 왼쪽 방향
c = length - 1 - c # 열의 순서를 반대로 변환
return [r, c] # 변환된 행렬 좌표 [r, c] 반환
q = deque() # BFS를 위한 큐 생성
q.append([1, 0]) # 초기 상태: 시작 지점(square 1)과 이동 횟수(moves 0)
visit = set() # 방문한 칸을 기록하는 집합
while q: # BFS를 계속 수행
square, moves = q.popleft() # 현재 칸(square)과 이동 횟수(moves)를 가져옴
for i in range(1, 7): # 주사위를 던져 1부터 6까지 이동 시도
nextSquare = square + i # 주사위 값만큼 이동한 다음 칸 계산
r, c = inToPos(nextSquare) # 다음 칸의 행렬 좌표 계산
if board[r][c] != -1: # 사다리나 뱀이 있다면 목적지로 이동
nextSquare = board[r][c]
if nextSquare == length * length: # 마지막 칸에 도달하면 종료
return moves + 1 # 현재 이동 횟수에 1을 더해 반환
if nextSquare not in visit: # 방문하지 않은 칸이라면
visit.add(nextSquare) # 방문 기록 추가
q.append([nextSquare, moves + 1]) # 큐에 다음 상태 추가
return -1 # BFS를 종료했는데도 마지막 칸에 도달하지 못하면 -1 반환
'LeetCode > Top Interview 150' 카테고리의 다른 글
212. Word Search II (0) | 2024.12.26 |
---|---|
211. Design Add and Search Words Data Structure (1) | 2024.12.26 |
149. Max Points on a Line (4) | 2024.12.23 |
50. Pow(x, n) (0) | 2024.12.22 |
69. Sqrt(x) (0) | 2024.12.22 |