开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情
引言
算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。
题目描述
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
0 <= j <= nums[i]i + j < n
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
提示:
1 <= nums.length <= 1040 <= nums[i] <= 1000
分析
**思路: 当前遍历到的地方一定是已经是当前位置最优的,然后当前能包含的范围[l, R]和与当前位置同最优的右端点[l, r]范围进行比较,如果R>r,则去更新[r+1, R]这段区间,然后用差分前缀和维护一下,注意细节pre要开到n+1,然后两个取min的地方 时间复杂度:O(n)
解答
class Solution { public: int jump(vector<int>& a) { int n = (int)a.size(); vector<int>pre(n + 1); for(int l = 0, r = 0; l < n; ++l) { if(l) pre[l] += pre[l - 1]; int R = a[l] + l; if(R > r) { pre[min(n, r + 1)] += pre[l] + 1; pre[min(n, R + 1)] -= pre[l] + 1; r = R; } } return pre[n - 1]; } };
总结
上面的算法思路让我学到了许多知识啊,希望大家继续努力,继续加油啊,加油。哈哈哈哈