You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.
Return true if you can reach the last index, or false otherwise.
class Solution:
def canJump(self, nums: List[int]) -> bool:
정수 리스트nums
가 있고, 인덱스에 저장된 값 이하의 범위로 다음 인덱스로 이동할 수 있습니다. 그렇게 마지막 인덱스까지 도달할 수 있는지 bool
값을 반환하는 문제입니다. 만약 특정 리스트의 원소 값이 0
이라면 해당 인덱스에선 이동하지 못합니다.
제가 생각한 코드는 다음과 같습니다.
class Solution:
def canJump(self, nums: List[int]) -> bool:
zero_idx = None
now_idx = len(nums)-1
if nums[-1] == 0: # 끝이 0인 경우
now_idx -=1
if nums[0] == 0: # 시작이 0인 경우
return False if len(nums)>1 else True
while now_idx >= 0:
if nums[now_idx] == 0:
zero_idx = now_idx
now_idx-=1
while nums[now_idx]+now_idx <= zero_idx:
if now_idx == 0:
return False
now_idx-=1
else:
now_idx-=1
return True
zero_idx
: nums
리스트를 탐색하는 도중 0이 나온 지점의 인덱스를 저장하는 변수.now_idx
: 탐색하는 지점의 인덱스 변수. 역순으로 탐색할 예정이므로 len(nums)-1
로 초기화.0
을 넘지 못한다면 False
지만,0
이라면 마지막을 넘지 못하는건 제외해야 하므로 끝에서 두번째 인덱스에서 시작합니다.0
이라면 원래 False
입니다. 하지만 길이가 1
이면 마지막 원소에 도달한 상태이므로 True
를 반환합니다.0
이 나타나면 zero_idx
에 인덱스를 저장하고 다음 원소로 넘어갑니다.zero_idx
를 넘는 값을 가질때까지 새로운 내부 whlie문
에서 역순회를 이어갑니다. zero_idx
를 넘는 원소가 나타나지 않는다면 False
를 반환합니다.zero_idx
를 넘는 원소가 나왔다면 내부 while문
을 벗어나면서 다시 외부 while문
으로 이동합니다.외부 while문
을 벗어난다면 True
를 반환합니다.이 문제에 대해 고민할 때 제가 생각한 포인트는 결국 0
값을 가지는 지점을 뛰어넘을수 있는가가 요점이라는 생각을 했습니다.
따라서 0이 나오는 지점을 확인하기 위해 zero_idx
를 두었고 이전의 지점들이 zero_idx
를 넘는다면 해당 0
값은 지날 수 있다고 여겼습니다.
이 방식으로 모든 0
을 넘는다면 while문을 모두 탈출하여 True
를 반환하도록 코딩했습니다.
역순으로 한 이유는 한 방향으로 한 번에 마무리를 생각했기 때문입니다.
근데 지금 다시 생각해보니 순방향도 가능하겠네요..? 그냥 순방향으로 돌면서 최대로 이동할 수 있는 값을 업데이트하면 되겠네요.. 더 쉬운거 같다.....
생각난 김에 코드를 작성해봤습니다.
class Solution:
def canJump(self, nums: List[int]) -> bool:
if nums[0] == 0: # 시작이 0인 경우
return False if len(nums)>1 else True
if nums[-1] == 0: # 끝이 0인 경우
nums = nums[:-1]
possible_max_idx = 0
for idx,num in enumerate(nums):
if possible_max_idx < idx+num:
possible_max_idx = idx+num
if num==0 and possible_max_idx <= idx:
return False
return True
음... 이렇게 하니까 진짜 된다.. 성능도 별 차이없네요..
앞에서부터 최대로 이동 가능한 지점을 갱신하면서 0
이 나올때 최대 지점이 0
을 못넘는다면 False
를 반환하고 반복문이 끝나면 True
를 반복하게 하니까 됩니다.
웃프다..