贪心算法||力扣刷题,L122.买卖股票的最佳时机II 、L55. 跳跃游戏、L45.跳跃游戏II

文章介绍了在LeetCode上的两道题目,分别是买卖股票的最佳时机II和跳跃游戏系列。对于股票问题,解决方案是通过比较相邻两天的股票价格来获取最大利润,使用双指针优化算法。跳跃游戏则涉及判断能否到达数组的最后一个位置,通过不断更新最大跳跃范围来求解。
摘要由CSDN通过智能技术生成

122. 买卖股票的最佳时机 II - 力扣(LeetCode)

思路:

1、在这自己采用双指针的方式,因为只需要判断当天的股票价格与第二天股票价格是否盈利,若盈利,就买,采用这种方式

2、若不盈利,就不够买此股票,就让当前慢指针指向第二天的股票值。

3,、若后面的股票一直都是在涨,就保持当前慢指针不动,一直让快指针向后移动,直到遇到开始亏钱,出现负盈利,再更新慢指针。

class Solution {
public:
    int maxProfit(vector<int>& prices)
    {
        if (prices.size() <= 1)return 0;
        int profit = 0;
        int fast = 0;//用来判断当快指针是否到达最后一天了,若到达,说明,最后一天相对于前一天来说也是盈利的,要加上
        int slow = 0;//慢指针
        for (int i = 0; i < prices.size() - 1; i++)//要将最后一天留出来,这样避免代码超出空间
        {
            if (prices[i + 1] > prices[i])//如果第二天股票价格比当天价格高,就让快指针向后移动,并且fast用来记录第几天
            {
                fast = i + 1;
            }
            else//若不满足,就让慢指针指向第二天股票价格
            {
                profit += (prices[i] - prices[slow]);//因为满足不盈利了,说明第i天到slow还是盈利的,所以需要加上此利润
                slow = i + 1;//让慢指针指向第二天
            }
            if (fast == prices.size() - 1)//这是用来判断是否处于最后一天,是否盈利,若等于,说明最后一天是盈利的,加上最后一天的盈利
            {
                profit += (prices[fast] - prices[slow]);
            }
        }
        return profit;
    }
};

在看完卡哥代码,才发现想复杂了,好的算法,真的想不到

卡哥思路是,判断第二天减去第一天价格是否大于0,若大于0 说明是盈利的,只要盈利就加上,依次向后走,直到遍历完整个数组,最后的盈利也就是最大盈利。

这里主要考虑的一个点便是,我可以当天卖掉我的股票,然后又买进来。这个总和是不变的。

int maxprofit(vector<int>& prices)
{
    int result = 0;
    for (int i = 0; i < prices.size(); i++)
    {
        result += max(prices[i] - prices[i - 1], 0);
    }
    return result;
}

55. 跳跃游戏 - 力扣(LeetCode)

思路;

因为是要判断是否能跳到最后一格,在这我们应该先分清

跳跃到达的位置应该是:数组下标+当前下标的值

若能够达到最后一个位置应该是:当前最大跳跃位置>=数组大小-1;

我们就可以在这里开始判段,因为每个小标的跳跃到达位置也就是可达到的范围

不断在此范围内,遍历,下标,选取能够到达的最大跳跃位置,判断是否满足条件即可。

并且这个遍历范围也是不断改变,是随着最大范围的变化而变化:

注意:在这不需要考虑是否会超出数组范围,因为一旦超出,就会跳出循环,不会往下面遍历。

class Solution {
public:
    bool canJump(vector<int>& nums) 
    {
        int cover = 0;//定义一个跳跃到达位置
        if (nums.size() <= 1)return true;//若当前数组值小于等于1,说明已经达到
        for (int i = 0; i <= cover; i++)//开始遍历
        {
            cover = max(i + nums[i], cover);//不断更新最大跳跃的范围
            if (cover >= nums.size() - 1)return true;//只要一旦满足,就会退出循环,若不满足,cover值是小于数组长度,故不会越界。
        }
        return false;
    }
};

45. 跳跃游戏 II - 力扣(LeetCode)

说实话,这题比上题难多了,因为不知道如何确定我是否要跳一步,要想好久

解题思路:

根据上题,跳跃位置与能否达到最后一个位置是一样计算的。

这个跳跃位置也是要等于数组下标的,在这定义两个范围,一个就是在当前可用范围,另一个就是当前可用范围内的最大可覆盖范围。

int curCover=0;//当前可用范围,寻找范围
int nextCover=0;//当前可用范围内的最大范围

 当我们遍历到当前下标值等于可用范围时,说明我们需要跳一下

因为当前可用范围就是我们能够在当前达到的最大范围,若已经到达最大范围还是没能够到达最后一个值,说明我们要往后面走一步,看看新的范围,

若在当前范围内,nextCover值大于数组长度,说明能够达到,我们直接跳出循环即可,若不能,就让当前范围,等于此范围内的最大范围值,更新此范围,向后走。

因为当处于0的阶段已经考虑进去,故代码符合逻辑。

并且若curCover不能往后面走了,当遍历完整个数组,也会返回一个值,就是0,说明不能通过跳跃达到后面。

也就是说我现在最大能调到的位置也就是不能达到最后。

注意:这里跳跃次数一定要写在判断条件之前。因为无论如何,我至少都是一次,只有满足之后我才不用跳。

class Solution {
public:
    int jump(vector<int>& nums) 
    {
        if (nums.size() == 1)return 0;
        int curCover = 0;
        int result = 0;
        int nextCover = 0;//记录当前下一个的最大覆盖范围
        for (int i = 0; i < nums.size(); i++)
        {
            nextCover = max(i + nums[i], nextCover);
            if (i == curCover)
            {
                result++;
                curCover = nextCover;
                if (nextCover >= nums.size() - 1)break;
            }
        }
        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值