Jump Game II
LeetCode 45. Jump Game II
원문
You are given a 0-indexed array of integers nums
of length n
. You are initially positioned at nums[0]
.
Each element nums[i]
represents the maximum length of a forward jump from index i
. In other words, if you are at nums[i]
, you can jump to any nums[i + j]
where:
0 <= j <= nums[i]
andi + j < n
Return the minimum number of jumps to reach nums[n - 1]
. The test cases are generated such that you can reach nums[n - 1]
.
풀이
- 이동 횟수를 저장하기 위한 리스트
dp
를 생성한다. 길이는nums
와 같고, 각 원소는int(1e9)
로 초기화한다. nums
의 마지막부터 순회한다. 이때의 인덱스를i
라 하면 반복문 안에서i
부터nums
의 마지막까지 순회한다.nums[i] + i
가 안쪽 반복문의 인덱스j
보다 크거나 같으면서dp[i]
가dp[j] + 1
보다 크다면dp[i]
를dp[j] + 1
로 갱신한다.- 바깥 반복문까지 순회가 모두 끝나면
dp[0]
을 반환한다.
코드
1
2
3
4
5
6
7
8
9
10
11
class Solution:
def jump(self, nums: List[int]) -> int:
dp = [int(1e9) for i in range(len(nums))]
dp[-1] = 0
for i in range(len(nums) - 1, -1, -1):
for j in range(i, len(nums)):
if nums[i] + i >= j and dp[i] > dp[j] + 1:
dp[i] = dp[j] + 1
return dp[0]
다른 풀이
기존 풀이가 너무 느려(14782ms) solutions
탭을 보니 탐욕법 풀이가 있었다.
- 우선 최대로 접근할 수 있는 위치를 저장하기 위한 변수
reach
, 이동 횟수를 저장하기 위한 변수cnt
, 도달한 인덱스 중 가장 큰 값을 나타내는last
를 선언한다. 초기값은 모두 0이다. len(nums) - 1
번째 원소까지 순회한다. 이때 인덱스는i
로 표현한다.reach
를reach
와nums[i] + i
중 더 큰 값으로 갱신한다.i
가last
와 같다면last
를reach
로 갱신하고,cnt
에 1을 더해준다.
- 순회가 끝나면
cnt
를 반환한다.
122ms
코드
Python
1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
def jump(self, nums: List[int]) -> int:
reach, cnt, last = 0, 0, 0
for i in range(len(nums) - 1):
reach = max(reach, i + nums[i])
if i == last:
last = reach
cnt += 1
return cnt
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int jump(int[] nums) {
int result = 0;
int reach = 0;
int last = 0;
for (int i = 0; i < nums.length - 1; i++) {
reach = Math.max(reach, i + nums[i]);
if (i == last) {
last = reach;
result++;
}
}
return result;
}
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.