45.ジャンプゲームII
トピック
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
問題解決のアイデア
1>ソースコード
# 贪心
class Solution:
def jump(self, nums: List[int]) -> int:
n = len(nums)
steps = 0
maxpos = 0
end = 0
for i in range(n-1):
if maxpos>=i:
maxpos = max(maxpos, nums[i]+i)
if i==end:
steps += 1
end = maxpos
return steps
# 超时
class Solution:
def jump(self, nums: List[int]) -> int:
n = len(nums)-1
steps = 0
while n>0:
for i in range(n):
if i+nums[i]>=n:
steps += 1
n = i
break
return steps
2>アルゴリズムの紹介
この問題は欲張りアルゴリズムの問題ですが、この問題を最初に見たとき、力ずくの方法を使用して問題を解決することを考えました。つまり、最後の要素から開始して、現在の位置にジャンプできる最も遠い要素が現在の要素の前に見つかるたびに、次に例を示します。
[2,3,1,1,4]
最後の要素は4(nums [4])です。4の前にジャンプできる最後の要素はnums [1]とnums [3]です。最も遠い要素を見つける必要があるのはnums [1]です。
このメソッドの時間計算量はO(n ^ 2)であり、この質問ではタイムアウトになります。
この質問の別の方法は非常に賢いですが、それでも欲張りアルゴリズムのアイデアを使用しています、例えば:
[2,3,1,1,4]
最初の要素の場合、nums [0]が到達できる位置はnums [1]とnums [2]であり、nums [1]はnums [4]に最も遠くに到達でき、nums [2]はnumsに最も遠くに到達できます[ 3]なので、nums [1]を選択します。
上記のように次の手順も使用できるため、この例のジャンプはnums [0]-> nums [1]-> nums [4]です。このアイデアにより、この質問の時間計算量をO(n)に最適化できます。
ただし、この質問で最も独創的なのはアルゴリズムではなく、このアルゴリズムの実装です。特定の実装については、コードを参照してください。