法1:贪心
Python
问:为什么代码只需要遍历到 n−2?
答:当 i=n−2 时,如果 i<curRight,说明可以到达 n−1;如果 i=curRight,我们会造桥,这样也可以到达 n−1。所以无论是何种情况,都只需要遍历到 n−2。或者说,n−1 已经是终点了,你总不能在终点还打算造桥吧?
问:我能想出这题的思路,就是代码实现总是写不对,有没有什么建议?
答:清晰的变量名以及一些必要的注释,会对理清代码逻辑有帮助。在出现错误时,可以用一些小数据去运行你的代码,通过 print 或者打断点的方式,查看这些关键变量的值,看看是否与预期结果一致。
问:如果题目没有保证一定能到达 n−1,代码要怎么改?
答:见 1326.灌溉花园的最少水龙头数目,我的题解。
class Solution:
def jump(self, nums: List[int]) -> int:
res = 0
cur_right = 0 # 当前桥的右端点
next_right = 0 # 下座桥的右端点
n = len(nums)
for i in range(n-1):
next_right = max(next_right, i + nums[i])
if cur_right == i:
res += 1
cur_right = next_right
return res
Java
贪心是最优解法,必须掌握!重点理解,看B站视频辅助!!!
在具体的实现中,我们维护当前能够到达的最大下标位置,记为边界。我们从左到右遍历数组,到达边界时,更新边界并将跳跃次数增加 1。
在遍历数组时,我们不访问最后一个元素,这是因为在访问最后一个元素之前,我们的边界一定大于等于最后一个位置,否则就无法跳到最后一个位置了。如果访问最后一个元素,在边界正好为最后一个位置的情况下,我们会增加一次「不必要的跳跃次数」,因此我们不必访问最后一个元素。
class Solution {
public int jump(int[] nums) {
int res = 0, end = 0, maxPos = 0;
for (int i = 0; i < nums.length - 1; ++i) {
maxPos = Math.max(maxPos, nums[i] + i);
if (i == end) {
++res;
end = maxPos;
}
}
return res;
}
}