https://leetcode.com/problems/jump-game/

 

  • 입력
    • int [] nums
  • 출력
    • 마지막 인덱스에 도달할 수 있는지 여부 boolean

메모이제이션

첫 위치는 0번 인덱스에서 시작된다. 그리고 해당 인덱스의 값인 nums [i]는 최대 점프 길이를 뜻한다.

먼저 문제를 이해하기 이해 하나씩 해보겠다.

[2, 3, 1, 1, 4] 의경우 idx 기준으로 0 → 1→ 4 가 가능하다. 또 0 → 2→ 3 → 4로도 가능하다.

다른 경우를 하나 더 생각해보자. 0 → 1 → 2 → 3 → 4의 경로도 가능하다.

위의 예시에서 보면 알 수 있는 게 있다. 바로 2 → 3 → 4가 반복되고 있다는 것이다.

다시 말해 해당 번호에서 출발하는 경로가 반복돼서 나타나는데 만약 그 경로로부터 도착할 수 없다면 더 이상 탐색할 필요가 없다는 것이다.

필요한 것은 해당 idx에서 도달 가능한 지를 저장하는 테이블이다.

class Solution {
    public boolean canJump(int[] nums) {
	  // false와 true만 있으면 판정이 힘들기 때문에 null이 가능하도록 Boolean 배열로 생성
        Boolean[] isPossible = new Boolean[nums.length];
        return dfs(0, nums, isPossible);
    }

    private boolean dfs(int v, int[] nums, Boolean[] isPossible) {
        if (v >= nums.length - 1) {
            return true;
        }

        if (isPossible[v] != null) {
            return isPossible[v];
        }

        for (int u = v + 1; u <= v + nums[v]; u++) {
            if (dfs(u, nums, isPossible)) {
	            // 재귀를 모두 통과했다는 것은 방문이 가능하다는 것.
                return isPossible[v] = true;
            }
            if (u >= nums.length - 1) {
            // 범위를 벗어난 것은 볼 필요 없다.
                break;
            }
        }
				// 모든 지점을 확인했는데도 true를 리턴하지 못했다는 것은 방문하지 못한다는 것
        return isPossible[v] = false; 
    }
}

하지만 이 알고리즘은 최악의 경우 O(N^2)의 시간복잡도를 가진다. 실제로는 메모이제이션으로 인해 더 적은 시간이 소요되겠지만 여전히 비효율적이다.

그리디 알고리즘

각 위치에서 최대한 멀리 갈 수 있는지를 판단하면 전체적인 도달 가능성을 확인할 수 있다.

즉 현재 최대로 도달 할 수 있는 위치를 기록하고 현재 인덱스가 그보다 크면 도달할 수 없다는 뜻이므로 false를 반환한다.

도달할 수 있다면 최대 도달 위치를 갱신해 준다.

class Solution {
    public boolean canJump(int[] nums) {
        int max = 0; // 도달할 수 있는 최대 위치

        for (int i = 0; i < nums.length; i++) {
            // 최대 이동 위치보다 먼 곳 = 도달할 수 없는 곳
            if (i > max) {
                return false;
            }
            // 만약 현재 위치에서 더 멀리 갈 수 있다면 그 위치로 최대 위치를 갱신
            max = Math.max(max, i + nums[i]);
        }

        return true;
    }
}

이 방법이면 O(N)의 시간복잡도로 해결이 가능하다.

'Algorithm > LeetCode' 카테고리의 다른 글

LeetCode 274 - H-Index  (0) 2024.09.29
LeetCode 45 - Jump Game2  (0) 2024.09.29
LeetCode 122 - Best Time to Buy and Sell Stock 2  (3) 2024.09.28
LeetCode 189 - Rotate Array  (0) 2024.09.28
LeetCode 80 - Remove Duplicates from Sorted Array 2  (0) 2024.09.28

+ Recent posts