BFS와 DP 두 가지 방식으로 풀었다.
x부터 시작해서 +n, 2, 3 연산으로 y에 도달하는 최소 횟수
핵심: visit 배열로 이미 방문한 노드 체크
→ visit 없으면 같은 노드를 무한히 방문해서 시간초과!
→ visit 있으면 각 노드를 최대 한 번만 방문 → O(y)
dp[i] = x에서 i로 가는 최소 연산 횟수
순방향으로 갱신:
dp[i+n] = min(dp[i+n], dp[i] + 1)
dp[i2] = min(dp[i2], dp[i] + 1)
dp[i3] = min(dp[i3], dp[i] + 1)
dp[i] = min(dp[i-n], dp[i/2], dp[i/3]) 로 구현하면
→ i가 n으로 나누어지지 않거나 2, 3으로 나누어지지 않는 경우 처리 복잡
→ 도달 불가능(-1) 케이스 처리도 어려움
순방향이 훨씬 자연스럽고 구현이 쉬움!
O(y) = O(1,000,000) → 충분히 가능
1억번 연산 ≈ 1초 기준으로
O(n) = 100만번 → 가능 ✅
O(n²) = 1조번 → 시간초과 ❌
import java.util.*;
class Point {
int now, cnt;
public Point(int now, int cnt) {
this.now = now; this.cnt = cnt;
}
}
class Solution {
public int solution(int x, int y, int n) {
return bfs(x, y, n);
}
public int bfs(int x, int y, int n) {
Queue<Point> q = new LinkedList<>();
q.offer(new Point(x, 0));
boolean[] visit = new boolean[y+1];
visit[x] = true;
while (!q.isEmpty()) {
Point p = q.poll();
if (p.now == y) return p.cnt;
int[] next = {p.now + n, p.now * 2, p.now * 3};
for (int cal : next) {
if (cal > y || visit[cal]) continue;
visit[cal] = true;
q.offer(new Point(cal, p.cnt + 1));
}
}
return -1;
}
}
import java.util.*;
class Solution {
public int solution(int x, int y, int n) {
int[] dp = new int[y+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[x] = 0;
for (int i = x; i <= y; i++) {
if (dp[i] == Integer.MAX_VALUE) continue; // 도달 불가능한 노드 skip
if (i + n <= y) dp[i+n] = Math.min(dp[i+n], dp[i] + 1);
if (i * 2 <= y) dp[i*2] = Math.min(dp[i*2], dp[i] + 1);
if (i * 3 <= y) dp[i*3] = Math.min(dp[i*3], dp[i] + 1);
}
return dp[y] == Integer.MAX_VALUE ? -1 : dp[y];
}
}
dp[i] == Integer.MAX_VALUE일 때 +1 하면 오버플로우가 발생하므로 반드시 skip해야 한다.