动态规划I (45、55、62、63)

按顺序刷确实效率太低了,今天开始要按顺序的同时也按标题来了,全面加油!这种应该以后会更多直接总结题解了,自我学习用,全靠大佬,贴贴!!含45、55、62、63

CP55 跳跃游戏

题目描述:

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标。

题解:

动态规划I (45、55、62、63)_第1张图片

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

大佬!:

动态规划I (45、55、62、63)_第2张图片

 按这个思路去写,结果超时...我的问题在于,本题需要的是最后一个格子可不可以,我们只需要找到每次跳得最远得地方,我这里定义了一个数组tmp存储每一个地方能不能被跳到,但是这是完全没有用得,更远得能被跳到,那后面得一定可以跳到,无需维护这个数组,只需要记录最远可以跳到得地方。

//我写的超时破代码
class Solution {
public:
    bool canJump(vector& nums) {
        int length=nums.size();
        vector tmp(length);
        tmp[0]=true;

        for(int i=0;i
//大佬代码
class Solution {
public:
    bool canJump(vector& nums) {
        int k = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (i > k) return false;
            k = max(k, i + nums[i]);
        }
        return true;
    }
};

CP45 跳跃游戏II

题目描述:

给定一个长度为 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]。注:题目保证可以到达 nums[n-1]

学习记录:

有了第一题的想法,我们只需要不断判断每次的最小步数就行了,初步想法是定义一个储存最小步数的数组,然后不断更新。一道典型的动态规划

//我的思路
class Solution {
public:
    int jump(vector& nums) {
        int length=nums.size();
        vector tmp(length);//存储最少跳数 
        for(int i=0;i

题解:

1.正向分析法

其实我们也用了正向分析法,但是正如第一题提到的问题,所有后面能到达的前面也能,同理不用多维护一个数组,在本题,最后一个点一定能到,也就是说这个数组中所有点都是能到的。所以我每次只需要:我们维护当前能够到达的最大下标位置,记为边界。我们从左到右遍历数组,到达边界时,更新边界并将跳跃次数增加 1。比我们的方案难理解一点,maxPos:目前能跳到的最远位置;end:上次可跳跃的右边界

动态规划I (45、55、62、63)_第3张图片 

class Solution {
public:
    int jump(vector& nums) {
        int maxPos = 0, n = nums.size(), end = 0, step = 0;
        for (int i = 0; i < n - 1; ++i) 
        {
            maxPos = max(maxPos, i + nums[i]);
            if (i == end) 
            {
                end = maxPos;
                ++step;
            }
        }
        return step;
    }
};

2.反向分析法

C++实现超时间了,就学习一下思想,给出java实现的代码

动态规划I (45、55、62、63)_第4张图片

class Solution {
    public int jump(int[] nums) {
        int position = nums.length - 1;
        int steps = 0;
        while (position > 0) {
            for (int i = 0; i < position; i++) {
                if (i + nums[i] >= position) {
                    position = i;
                    steps++;
                    break;
                }
            }
        }
        return steps;
    }
}

CP62 不同路径

题目描述:

动态规划I (45、55、62、63)_第5张图片 

学习记录:

典型动态规划,维护一个数组,记录路径数即可。

class Solution {
public:
    int uniquePaths(int m, int n) {
        int tmp[m][n];
        for(int i=0;i

题解:

除了上述方法,还有一种

动态规划I (45、55、62、63)_第6张图片

python中存在API:

def uniquePaths(self, m: int, n: int) -> int:
        return int(math.factorial(m+n-2)/math.factorial(m-1)/math.factorial(n-1))

作者:powcai

CP63 不同路径II

题目描述:

动态规划I (45、55、62、63)_第7张图片

学习记录:

和上述思路一样,只是多加了一个判断,如果有石头就不能走,没啥好说的,写

class Solution {
public:
    int uniquePathsWithObstacles(vector>& obstacleGrid) {
        int m=obstacleGrid.size();int n=obstacleGrid[0].size();
        int tmp[m][n];
        int flag=1;
        for(int i=0;i

注:定义可以这样定义:vector> tmp(m,vector(n));

 

PS:

由于leetcode比较智能允许int t[m][n]这种形式,但是VS2010不行,需要方法如下:

#include    
#include 
#include 
using namespace std;

void find(int m,int n)
{
	int *m1=new int [m];
	for(int i=0;i

你可能感兴趣的:(即时学习,动态规划,算法,数据结构)