πŸ“ μ•Œκ³ λ¦¬μ¦˜/Dynamic Programming

[LeetCode] 403. Frog Jump (해석, Java 풀이)

점이 2023. 8. 28. 22:16
λ°˜μ‘ν˜•

문제

https://leetcode.com/problems/frog-jump/description/

κ°œκ΅¬λ¦¬λŠ” 강을 κ±΄λ„Œλ‹€. 강은 λͺ‡κ°œμ˜ unit으둜 λ‚˜λ‰˜μ–΄μ Έμžˆκ³ , κ·Έκ³³μ—λŠ” 돌이 μžˆμ„ μˆ˜λ„ 있고 μ—†μ„μˆ˜λ„ μžˆλ‹€. κ°œκ΅¬λ¦¬λŠ” 돌 μœ„μ—μ„œ 점프할 수 있으며 물둜 λ›°μ–΄λ“€μ–΄μ„  μ•ˆλœλ‹€.

μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬λœ stones(돌)의 μœ„μΉ˜ λ¦¬μŠ€νŠΈκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, κ°œκ΅¬λ¦¬κ°€ λ§ˆμ§€λ§‰ λŒμ— μ°©λ₯™ν•˜λ©° 강을 건널 수 μžˆλŠ”μ§€ νŒλ³„ν•˜λΌ. 처음 κ°œκ΅¬λ¦¬λŠ” 첫번째 돌 μœ„μ— μ„œ 있으며, 첫번째 μ ν”„λŠ” 1 unitλ§ŒνΌμ΄λ‹€.

λ§Œμ•½ 개ꡬ리의 λ§ˆμ§€λ§‰ jumpκ°€ k unitλ§ŒνΌμ΄μ—ˆλ‹€λ©΄, λ‹€μŒ μ ν”„λŠ” k-1, k λ˜λŠ” k+1 unitλ§ŒνΌμ΄μ–΄μ•Ό ν•œλ‹€. κ°œκ΅¬λ¦¬λŠ” 였직 μ•žμœΌλ‘œλ§Œ 갈 수 μžˆλ‹€.

풀이

public class LeetCode_403_FrogJump {

    HashMap<Integer, Integer> m = new HashMap<>();

    boolean[][] canGo;
    boolean[][] visited;

    public boolean canCross(int[] stones) {
        if(stones[1] - stones[0] > 1) return false;
        for (int i = 0; i < stones.length; i++) {
            m.put(stones[i], i);
        }
        dp = new boolean[stones.length][stones.length];
        visited = new boolean[stones.length][stones.length];
        return dp(1, 1, stones);
    }

    private boolean dp(int stone, int jump, int[] stones) {
        if (stone == stones.length - 1) return true;       // λκΉŒμ§€ μ™”λ‹€λ©΄ True
        if (visited[stone][jump]) return canGo[stone][jump];   // 듀린적이 μžˆλ‹€λ©΄, ν•΄λ‹Ή κ°’ κ·ΈλŒ€λ‘œ μ‚¬μš©

        boolean canJump = false;
        for(int j : new int[]{jump - 1, jump, jump + 1}) {
            if(j > 0 && m.containsKey(stones[stone] + j)) {
                canJump = (canJump || dp(m.get(stones[stone] + j), j, stones));
            }
        }

        visited[stone][jump] = true;
        canGo[stone][jump] = canJump;

        return canGo[stone][jump];
    }
}

m: 돌이 μžˆλŠ” μœ„μΉ˜λ₯Ό μ‰½κ²Œ 인덱싱 ν•  수 μžˆλ„λ‘ λ§Œλ“  λ§΅

canGo[i][j]: i 번째 λŒμ—μ„œ j 만큼 μ ν”„ν–ˆμ„ λ•Œ, λκΉŒμ§€ 도달할 수 μžˆλŠ”μ§€

visited[i][j]: i 번째 λŒμ—μ„œ j 만큼 μ ν”„ν–ˆμ„ λ•Œλ₯Ό κ³„μ‚°ν•œ 적이 μžˆλŠ”μ§€

 

점프 ν•  수 μžˆλŠ” 거리( jump - 1, jump, jump + 1)에 stone이 μžˆλŠ”μ§€ ν™•μΈν•˜κ³ (containsKey), 

λ§Œμ•½ μžˆλ‹€λ©΄, 그곳으둜 μ „μ§„ν•œλ‹€. 

κ³„μ†ν•΄μ„œ 전진을 ν–ˆμ„ λ•Œ, μ΅œμ’…μ μœΌλ‘œ stones.length - 1 에 λ„λ‹¬ν•œλ‹€λ©΄,

λ§ˆμ§€λ§‰ 돌의 μœ„μΉ˜κΉŒμ§€ λ„λ‹¬ν•˜μ—¬ 강을 κ±΄λ„Œκ²ƒμœΌλ‘œ true둜 ν‘œμ‹œν•œλ‹€.

 

μ‹œκ°„ λ³΅μž‘λ„: O(n^2), 곡간 λ³΅μž‘λ„: O(n^2)

https://github.com/jeongum/java-algorithm/blob/master/dynamic_programming/LeetCode_403_FrogJump.java

λ°˜μ‘ν˜•