第28天|LeetCode122. 买卖股票的最佳时机 II、LeetCode55. 跳跃游戏、LeetCode45. 跳跃游戏 II

文章介绍了如何使用动态规划策略解决股票交易中的最大利润问题以及跳跃游戏中到达终点的最小步数问题。关键在于寻找局部最优解,如股票每日利润中的正数和跳跃中每次的最大覆盖范围。通过遍历和更新覆盖范围,确定全局最优解。
摘要由CSDN通过智能技术生成

1.题目链接:122. 买卖股票的最佳时机 II

题目描述:

                给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

                在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

                返回 你能获得的 最大 利润 

解法:

                1.此题全局最优解是获得最大利润,那么我要找到局部最优解。

                2.我们可以这样想,prices[3] - prices[0] = prices[3] - prices[2] + prices[2] - prices[1] +prices[1] - prices[0]。即将其表示成每一天的利润。那么只要利润是正数,就对总利润起增大的作用,如果小于0就起减少的作用。所以就收集正数就行。

                3.定义result用于收集最大利润。

                4.从i = 1开始遍历,因为我们要先买再卖。

                5.result += max.(nums[i] - nums[i-1], 0);

                6.最后返回result即可。

下面为代码(java):

2.题目链接:55. 跳跃游戏 

题目描述:

                给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

                数组中的每个元素代表你在该位置可以跳跃的最大长度。

                判断你是否能够到达最后一个下标。

解法:

                1.判断是否可以到达最后一个下标,那么我们要将此题想成覆盖范围的问题,而不是判断到哪个位置下一步该跳几部,这样就会很容易想到。

                2.那么要声明一个cover = 0,表示覆盖范围。我们要在覆盖范围内遍历才是有效的。

                3.cover = max.(cover, i+nums[i]);即在覆盖范围内求最大的覆盖范围是多少。

                4.if(cover >= nums.length -1){return true;}

                5.整个循环都遍历完了,都没有返回true就返回false。

                6.最后要考虑特殊情况,如果只有一个元素的话肯定可以跳到,因为最开始就指到第一个元素。

下面为代码(java):

3.题目链接:45. 跳跃游戏 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]。

解法:

                1.此题全局最优解是求最小跳跃次数,那么局部最优解就是要每次尽可能的向前跳,依旧用覆盖范围的思想来思考问题。

                2.定义当前覆盖范围 cur,定义下一次的覆盖范围 next,定义跳跃次数 result

                3.遍历整个数组,而不是在覆盖范围内遍历,这是此题和上题不同之处,因为此题有两个覆盖范围,我们之所以遍历整个数组是因为当我们遍历的指针指向cur的时候,说明当前覆盖范围遍历完了,然后看其和nums.length-1的关系,再决定是否进行下一次遍历。

                4.即for(int i = 0;i < nums.length.i++){

                        next = max.(i+nums[i],next) // 因为我们在当前覆盖范围内找到下一次的覆盖范围,我们要做的是每一次尽可能多的向前跳,所以我们求下一次覆盖范围的时候要取最大值

                        if(i == cur){// 判断当遍历到当前覆盖范围的时候,这里保证的就是上面的在当前覆盖范围内找下一次的覆盖范围。因为到i = cur的时候就开始判断了,所以next此时就收集了覆盖范围内的下一次覆盖范围。

                                if(cur < nums.length -1){//即当前覆盖范围没有跳到末尾,就要开启下次覆盖

                                        result++;

                                        cur = next;

                                        if(cur >= nums.length - 1){break;}// 即如果下一次的覆盖范围到了末尾,直接跳出,就求得了最小步数。

                                                }else{break;如果当前覆盖已经跳到末尾了,不用开启下次覆盖,直接跳出就得到了最小步数。

}

                5.最后return result

                6.同时要考虑特殊情况,如果数组长度就为1的话,那不用跳,直接次数就是0.

下面为代码(java):

4.总结:

                ①第一题:全局变量求最大利润,首先将每天的利润表示出来,然后只求正的利润---就是局部最优解。

                ②第二题:跳跃问题,用覆盖的思想来思考,在覆盖范围内遍历,然后更新覆盖范围,看其是否能覆盖到数组末尾。

                ③第三题:跳跃问题求最小次数---全局变量,局部变量---每次尽量向前跳。同样用覆盖的思想来解决。在整个数组范围内遍历,更新next的覆盖范围。同时要判断,当遍历到当前覆盖范围的时候,覆盖范围和整个数组长度的关系,如果不够就要开启下一次覆盖---即更新跳跃步数,更新cur,然后再判断cur和数组长度关系。如果够了,直接跳出,不用开启下次覆盖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值