55. 跳跃游戏
典型的贪心问题。对于一个可跳的序列:[2,3,1,1,4]存在一个问题就是,比如在位置1,可达区域就为1..=1+3,因此我只需要遍历当前可达区域内存在的跳跃能量是否支持我继续扩大可达区域,直到覆盖最后一个位置即可。
/// 55. 跳跃游戏pub fn can_jump(nums: Vec<i32>) -> bool {let mut max_arrive = 0;for x in 0..nums.len() {// 超过了可达区域,直接寄if x > max_arrive { return false; }max_arrive = max_arrive.max(x + nums[x] as usize);}true}
45. 跳跃游戏 II
相比上一题,这一题多了一个测算跳跃的最少步数。思路还是大体一样,找到当前的可达区域,探寻可达区域内能够跳到的最远位置,那么就从这个位置起跳。
看题解的图:
// 该题解的作者的代码int jump(vector<int> &nums){int ans = 0;int start = 0;int end = 1;while (end < nums.size()){int maxPos = 0;for (int i = start; i < end; i++){// 能跳到最远的距离maxPos = max(maxPos, i + nums[i]);}start = end; // 下一次起跳点范围开始的格子end = maxPos + 1; // 下一次起跳点范围结束的格子ans++; // 跳跃次数}return ans;}/// 45. 跳跃游戏 IIpub fn jump(nums: Vec<i32>) -> i32 {let (mut ans, mut start, mut end) = (0, 0, 1);while end < nums.len() {// 最大可达区间let mut max_arrive = 0;for i in start..end {max_arrive = max_arrive.max(i + nums[i]);}// 更新搜索区间start = end;end = max_arrive + 1;ans += 1;}ans}
优化一下:
/// 45. 跳跃游戏 IIpub fn jump(nums: Vec<i32>) -> i32 {let (mut ans, mut max_arrive, mut end) = (0, 0, 0);// 注意这个-1,不然在最后一个位置会多算一次for i in 0..nums.len()-1 {max_arrive = max_arrive.max(i + nums[i] as usize);if i == end {// 走到了上一个可达区间的末尾,更新为新的可达区间末尾end = max_arrive;ans += 1;}}ans}
1345. 跳跃游戏 IV
这一题已经进化为了图搜索问题,看图那一章
