算法分析与设计课程作业第六周#1

算法分析与设计课程作业第六周#1

这周学了贪心算法,就在leetcode上根据贪心算法的标签搜索了道medium题目来做。以下就是题目:

55. Jump Game

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. n及扩展

思路

因为题目的标签是贪心算法,所以就用贪心的思路去思考问题。那么怎么贪心呢?最开始的或者说最容易想到的思路就是从起点开始每跳都走最大步数,然而这样做的问题是并不能保证能到终点(即本来应返回true却返回了false),因为到终点的路径上的点并非一定恰好是其之前某点的走最大步数能到的点(例如如果要到终点必须经过第二个点,而第一个点最多能跳4步,就把第二个点跳过了),这样就会丢弃到终点的解,所以不可以。

**第一种思路:**
如果想不丢弃到终点的解(能到终点的就返回true),又想应用贪心算法的思想在每一格都考虑跳最大步数的话,可以考虑从终点开始向前遍历(能保证不丢弃能到终点的解了),每一格都考虑能跳最大步数,如果该格在其最大步数之内能到达终点,则将其标志为新的终点(能到该点就表示能到终点),从解决能否到终点的问题变为解决能否到该点(在终点之前)的子问题。遍历完,若标记的终点为起点,通过递推就说明从起点能到终点。
该算法时间复杂度为O(n),空间复杂度为O(1),应该没有比该思路更好的方法了。
该思路代码如下面第一块(找到思路后实现还是挺简单的)。

**第二种思路:**
虽然觉得无法做得更好(时间复杂度与空间复杂度上),但与上面的思路时间复杂度与空间复杂度一样的方法(同样也是应用贪心算法)还是有的(而且以下算法通常执行时间更短,下面解释为什么):
如果一定要从起点开始,每次依然考虑走最大步,但可以依然分析每个可达最远点之内的点,考虑每个可达最远点(而不是走最大步数能到达的点),记录能到的最远的点,如果能到的最远的点大于终点,就表明能到终点。注意我分析的是每个可达最远点之内的点,而不是分析每个点,如果我分析每个点并持续更新最远点,这个最远点并不一定是可达(因为并不一定每个点都可达),同时分析可达最远点之内的点保证了不会丢弃能到终点的解(可达最远点之前的点都是可达的,最远点之后的点都是不可达的)。从另一个角度来看,从这个方法的思路也可以知道:若一个点可达,则其之前的点均可达。
那么为什么这个算法通常执行时间更短呢,因为如果要返回false,即算法发现无法抵达终点,通常不需遍历整个数组,而在遍历过程的中间即可发现,而第一个算法则无论何时都必须遍历完整个数组。
该思路代码如下面第二块(留意循环其中一个终止条件是:i <= max)。

代码

第一种思路解决方法

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int lastpos = nums.size() - 1;
        for(int i = lastpos - 1; i >=0; i--){
            if(i + nums[i] >= lastpos){
                lastpos = i;
            }
        }
        return lastpos == 0;
    }
};

第二种思路解决方法

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int lastpos = nums.size() - 1;
        int max = 0;
        for(int i = 0; i <= max && i <= lastpos; i++){
            if(i + nums[i] >= max){
                max = i + nums[i];
            }
        }
        return lastpos <= max;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章