문제를 이해하기 어려워 지문부터 정리해보자면 다음과 같다.
grid
내의 모든 점이 가능하다. 즉, 모든 점을 시작점으로 고려해야 한다.위의 내용을 구현하기 위한 아이디어는 다음과 같다.
visited
)를 선언한다.visited
를 매 반복마다 초기화하면 안되는 이유다! 아래서 좀 더 자세히 설명해보겠다.)answer
에 사이클의 길이를 추가하며 종료한다.현재 방향을 기준으로 오른쪽, 혹은 왼쪽으로 움직이는 경우 다음과 같이 작성하면 쉽게 구현할 수 있다
# D, L, U, R 순으로 나열 (마름모 형태로 순환되어야 한다!)
dx = [1, 0, -1, 0]
dy = [0, -1, 0, 1]
# 왼쪽으로 이동
d = (d-1)%4
# 오른쪽으로 이동
d = (d+1)%4
[참고] visited
를 매 반복마다 초기화하면 안되는 이유
처음에 코드를 짤 때는 매 시작 지점/방향마다 사이클이 있는지 확인해야 한다고 생각해, 아래 코드처럼 매번 visited
를 초기화 해야 한다고 생각했다.
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
for(int k=0; k<4; k++){
visited = new int[n][m][4]; // 매 반복마다 vistied 초기화
int x = i, y = j, d = k;
int count = 0;
// 이하 생략
하지만, 이 경우 주어진 테스트 케이스에서 모든 경우에 다 사이클이 생성되는 것으로 판별했다!
즉, ["SL", "LR"] → [16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16] 식으로 결과가 나오는 것이다.
예시로 주어진 그림을 보며 그 이유를 확인할 수 있었다.
visited
가 매 반복마다 초기화 되면, 한 사이클에 속하는 경로로 시작하는 모든 경우를 새로운 사이클로 판별한다. 즉, 1번 경로에서 시작하나 5번 경로에서 시작 하나 모두 다른 사이클로 판별한다는 뜻이다. 하지만 우리가 원하는 것은 이 경우를 모두 같은 사이클로 취급하는 것이다.
그래서 한 번 방문한 경로는 다시 방문하지 않도록 visited
를 계속 갱신하여 문제를 해결할 수 있었다.
import java.util.*;
class Solution {
public int[] solution(String[] grid) {
int[] answer = {};
List<Integer> result = new ArrayList<Integer>();
int n = grid.length, m = grid[0].length();
int[][][] visited = new int[n][m][4];
int[] dx = {0, -1, 0, 1};
int[] dy = {-1, 0, 1, 0};
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
for(int k=0; k<4; k++){
int x = i, y = j, d = k;
int count = 0;
while(visited[x][y][d] == 0){
visited[x][y][d] = count++;
// 방향 전환
char now = grid[x].charAt(y);
if(now == 'R'){
d = (d + 1 + 4) % 4;
}else if(now == 'L'){
d = (d - 1 + 4) % 4;
}
// 좌표 이동
x = (x + dx[d] + n) % n;
y = (y + dy[d] + m) % m;
if(x == i && y == j && k == d){
result.add(count++);
break;
}
}
}
}
}
answer = new int[result.size()];
for(int i=0; i<result.size(); i++){
answer[i] = result.get(i);
}
Arrays.sort(answer); // 오름차순으로 값 정렬
return answer;
}
}
def solution(grid):
answer = []
visited = [[[0 for k in range(4)] for j in range(len(grid[0]))] for i in range(len(grid))]
dx = [1,0,-1,0] # D, L, U, R 순
dy = [0,-1,0,1]
for x in range(len(grid)):
for y in range(len(grid[0])):
for d in range(4):
nx, ny, nd = x, y, d
count = 0
while True:
if visited[nx][ny][nd] != 0:
break
count += 1
visited[nx][ny][nd] = count
nx = (nx + dx[nd]) % len(grid)
ny = (ny + dy[nd]) % len(grid[0])
if grid[nx][ny] == 'R':
nd = (nd+1)%4
elif grid[nx][ny] == 'L':
nd = (nd-1)%4
if (nx, ny, nd) == (x, y, d):
answer.append(count)
break
return sorted(answer)
.