1 题目
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
2 解法
2.1 从终点遍历的方法(时间复杂度)
计算出从后到前的所有格子到终点的最少步:
int jump(vector<int>& nums) {int nums_size = nums.size();if (nums_size <= 2) {return nums_size - 1;}vector<int> min_step_to_final(nums_size, 0);min_step_to_final[nums_size - 1] = 0;min_step_to_final[nums_size - 2] = nums[nums_size - 2] ? 1 : -1;for (int i = nums_size - 3; i >= 0; i --) {if (nums[i] >= nums_size - 1 - i)min_step_to_final[i] = 1;else {if (nums[i] == 0)min_step_to_final[i] = -1;else {int step_index = 1;int next_step = -1;while (step_index <= nums[i]) {if (min_step_to_final[i + step_index] != -1) {if (next_step == -1)next_step = min_step_to_final[i + step_index];elsenext_step = min(next_step, min_step_to_final[i + step_index]);}step_index ++;}if (next_step != -1)min_step_to_final[i] = next_step + 1;elsemin_step_to_final[i] = -1;}}}return min_step_to_final[0];}
2.2 总是寻找当前能到达的最远位置(贪心)(时间复杂度)
维护两个位置, 第一个是当前这步最远能到达的位置, 第一个是下一步最远能到达的位置, 遍历数组, 当索引值到达了当前这一步能到达的最远位置, 总步数加一, 当前步数最远到达位置赋值为下一步最远到达位置, 下一步最远到达位置清零:
int jump(vector<int>& nums) {int nums_size = nums.size();if (nums_size < 3)return nums_size - 1;int steps = 1;int current_step_max_pos = nums[0];int next_step_max_pos = 0;int index = 1;while (current_step_max_pos < nums_size - 1) {next_step_max_pos = max(next_step_max_pos, index + nums[index]);index ++;if (index > current_step_max_pos) {steps ++;current_step_max_pos = next_step_max_pos;next_step_max_pos = 0;}}return steps;}