算法课第18周第1题——55. Jump Game

来源:互联网 发布:淘宝怎么搜到假证 编辑:程序博客网 时间:2024/05/23 02:03

题目描述:

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

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

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.


程序代码:

解法1:

class Solution {public:bool canJump(vector<int>& nums) {// 处理nums为空的情况if (nums.size() == 0) {return false;}// 处理nums第一格为0的情况if (nums[0] == 0 && nums.size() != 1) {return false;}// step表示到的格标号,x表示到的格中的值int x = nums[0];int step = 0;while (step < nums.size() - 1) {step += x;if (step >= nums.size() - 1) {return true;}x = nums[step];nums[step] = 0;while (x == 0) {step--;x = nums[step];nums[step] = 0;if (step == 0) {return false;}}}return true;}};


解法2:

class Solution {public:bool canJump(vector<int>& nums) {int n = nums.size();// 最远可到的标号(可能超过size)int farthest = 0;int i;for (i = 0; i < n && i <= farthest; i++) {// 更新最远可到标号farthest = max(farthest, i + nums[i]);}if (i == n) {return true;}return false;}};


简要题解:

本题是一题用到贪心算法的题目。

先理清题意。本题的输入是一个数组,数组中的数字代表该格能往前跳的最大格子数,需要求出从第一格开始,最终能不能跳到最后一格。

 很快就可以发现本题可以利用贪心的策略来求解。不过这个贪心策略的选取还是需要进一步思考。一开始我考虑直接对每次能跳到的格子step来进行贪心策略,step根据nums[step]中的值不断更新,用x记录nums[step]的值,并将已经到达的nums[step]值置位0(因为最终如果到达不了最后一格,肯定是因为某格为0且无法到达该格后面导致,所以将到过的格置位0比较好处理),然后用一个循环,每次若发现x的值为0,则往后退一格,否则就根据nums[step]的值不断前进,直到step退回0返回false,或是step大等于n的值返回true。这个方法想起来比较常规,但是要处理的特殊情况特别多,比如首格为0等。

进一步思考更简单的贪心策略,我想到令farthest表示当前可能跳到的最远处的标号(farthest有可能超过数组的size,即有可能超过n),不难想到,farthest前的格子一定都是可以到达的。每往前推进一格,就根据贪心策略,令farthest的值取当前看来收效最快和最明显的那一个,即用farthest = max(farthest, i + nums[i])来更新farthest的值,这样farthest的值只会变大或不变(事实上也容易想到,每次更新后比farthest小的标号的点都是一定能到达的)。我们的循环(每次往前推进一格)只要保证i的值能小于n且小于等于farthest即可。当循环结束后,验证i是否等于n,即验证是否能推进到最后一格,即可判断最终结果。

通过本题,我复习了贪心算法的相关知识。这部分内容算法其实没有什么定式,而是一种思维方法,考虑下一步时就选择当前看来收效最快和效果最明显的那一个,在很多时候往往就能够达成目标。

原创粉丝点击