最少步数问题

707 阅读2分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。

Given an array of non-negative integers nums, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

You can assume that you can always reach the last index.

LeetCode

给定一个正整数数组,数组中的每个数代表最大能跳的步数,初始位置在数组0位置出发,目标到达数组最后一个位置(终点位置),求最少步数

一、分析

step:目前为止,跳了几步,初始值为0(一步也没跳)

cur:如果不增加步数(cover 不住的话,需要增加step),在step步之内,最远能到哪

next: 允许多跳一步,最远能到哪?

[3,] => step = 0,cur = 0,next = 3

image.png

来到1位置,就cover不住了,因为step = 0,最多能到 cur = 0,所以需要增加step,step = 1,

当增加step时,cur也要变,cur = next拷贝上来,cur = 3,next也要变更,允许多跳一步,最远能到哪,next = 1 + 4 = 5

来到2位置,需不需要增加步数,不需要,因为step = 1,一步以内,最远能到3(cur = 3),来到2位置,不需要增加step(步数),step、cur保持不动,next下一步做准备,2 + 1 = 3 < 5 ,不更新

来到3位置,也不需要增加步数,一步以内,最远能到3,需不需要为下一步next做准备,需要,因为 3 + 3 = 6 > 5,所以next = 5 => next = 6,多跳一步的话,能到6

来到4位置,需不需要增加步数,需要,因为一步之内,cover不了了,cur = 3 < 4,所以需要增加step步数,step++,step = 2,cur = 6(next拷贝上来),next = 4 + 2 = 6

...

当来到最后一个节点时,step就是最少步数

二、实现

    public static int jump(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        int step = 0;
        int cur = 0;
        int next = 0;
        for (int i = 0; i < arr.length; i++) {
            if (cur < i) { // cover不住,增加步数step
                step++;
                cur = next;
            }
            next = Math.max(next, i + arr[i]);
        }
        return step;
    }

三、总结

贪心:老奔着最大的数跳,也是不对的,比如一次就能到达终点,就算中间有大的,何必要选择呢?所以贪心并不是最好的