首页 > 编程语言 >算法随想Day29【贪心算法】| LC122买卖股票的最佳时机Ⅱ、LC55-跳跃游戏、LC45-跳跃游戏Ⅱ

算法随想Day29【贪心算法】| LC122买卖股票的最佳时机Ⅱ、LC55-跳跃游戏、LC45-跳跃游戏Ⅱ

时间:2023-03-04 11:33:30浏览次数:42  
标签:游戏 step nums int bound pos 算法 跳跃 size

LC122. 买卖股票的最佳时机Ⅱ

一旦遇到相比于昨天降价的,就抛出,就购入低价的,直到又遇到下一个滑坡点,又立即抛出,计算收益

贪心算法表现在:总是在降价前抛出,获取收益,总是在降价当前抛出

这道题的另一个思考角度是,对原数组如[7,1,5,3,6,4],除第一天外求取利润数组,即[-6, 4, -2, 3, -2],对所有正数相加求和即可。

int maxProfit(vector<int>& prices)
{
    ////因为0 <= prices[i] <= 10^4,在最后加多虚拟的一天,
    ////保证循环不变量,能够处理到最后一天,如例子[1, 2, 3, 4, 5]
    prices.emplace_back(-1);
    int sum = 0;
    int purchase = prices[0];  //当前所持股票
    for (int i = 1; i < prices.size(); ++i)
    {
        //一旦遇到相比于昨天降价的,就抛出,就购入低价的
        if (prices[i] < prices[i - 1])  
        {
            sum += (prices[i - 1] - purchase);  //计算换股票前赚的
            purchase = prices[i];
        }
        //else  //若升价,按兵不动
    }
    return sum;
}

LC55. 跳跃游戏

根据第一个数,设定初始右边界。对边界内的数,逐个找到可能存在的最右的边界,若能达到等于或超过最后一个元素的下标,即为true。

bool canJump(vector<int>& nums)
{
    if (nums.size() == 1)
    {
        return true;
    }
    int size = nums.size();
    int bound = nums[0];
    int pos = 1;
    while (pos <= bound)
    {
        if ((pos + nums[pos]) >= size - 1)
        {
            return true;
        }
        else if ((pos + nums[pos]) > bound)
        {
            bound = (pos + nums[pos]);
        }
        ++pos;
    }
    return false;
}

LC45. 跳跃游戏Ⅱ

跟上一题在大体逻辑上是一致的,如bound的划定和更新。但也要区分开来:

  • 上一题问的是是否可达,所以用while (pos <= bound)。本题说明一定可达nums[n - 1],求最小步数。所以只需while (pos <= size - 1)。

本题的关键,在于既然要计算最小步数,就要想清楚什么时候步数才一定要加一

  • 开始我的处理方式是,在上一题的基础上,加多一个loop_bound,标记当前step的最远覆盖范围,只有超过该值,才更新一次(loop_bound = bound;),同时step_inc_flag标志位保证pos在当前step的最远覆盖范围增加时,只step++一次。
  • 导致我辅助变量如此多的原因在于,变量的初始不应该从原数组的第二个元素算起,这样子在while内的处理能够更加地统一
int jump(vector<int>& nums)
{
    int size = nums.size();
    int bound = nums[0];
    int loop_bound = nums[0];  //记录这一step的最远覆盖范围
    bool step_inc_flag = 1;
    int pos = 1;
    int step = 1;
    int min_step = INT32_MAX;
    if (size == 1)  //如果只有一个元素,即已达终点
    {
        return 0;
    }

    if (bound >= size - 1)
    {
        return 1;
    }
    while (pos <= min(bound, size - 1))
    {
        if (pos <= loop_bound && step_inc_flag == 1)
        {
            ++step;
            step_inc_flag = 0;
        }
        else if (pos > loop_bound)
        {
            loop_bound = bound;
            step_inc_flag = 1;
            continue;
        }

        if ((pos + nums[pos]) >= size - 1 && step < min_step)
        {
            min_step = step;
        }
        if ((pos + nums[pos]) > bound)
        {
            bound = (pos + nums[pos]);
        }
        ++pos;
    }
    return min_step;
}

简短优化(参考Carl哥思路):

  • 初始pos、bound设立为0
  • 循环不变量,设定step = 1,如例子[1, 2],在循环内如果step不用增加,即达终点
int jump(vector<int>& nums)
{
    int size = nums.size();
    int bound = 0;
    int loop_bound = 0;  //记录这一step的最远覆盖范围
    int pos = 0;
    int step = 1;
    if (size == 1)  //如果只有一个元素,即已达终点
    {
        return 0;
    }
    while (pos <= size - 1)
    {
        if (pos > loop_bound)  //超过当前step的最远覆盖范围,才增加步数
        {
            step++;
            loop_bound = bound;
        }
        if ((pos + nums[pos]) > bound)  //检测是否更新最远覆盖范围
        {
            bound = (pos + nums[pos]);
        }
        if (bound >= size - 1)  //若最远覆盖范围,覆盖了终点,直接结束
        {
            break;
        }

        ++pos;
    }
    return step;
}

标签:游戏,step,nums,int,bound,pos,算法,跳跃,size
From: https://www.cnblogs.com/Mingzijiang/p/17177956.html

相关文章

  • 梯度提升算法决策过程的逐步可视化
    梯度提升算法是最常用的集成机器学习技术之一,该模型使用弱决策树序列来构建强学习器。这也是XGBoost和LightGBM模型的理论基础,所以在这篇文章中,我们将从头开始构建一个梯度......
  • (二)回溯算法: 组合数
    组合数问题描述给定两个整数n和k,返回范围[1,n]中所有可能的k个数的组合。感悟作为菜鸡的自己,这题一直是自己的心头之恨,上次和好友打比赛,遇到这题直接卡顿,想法......
  • (一)回溯算法
    概念:什么是回溯算法:回溯算法是对问题的一种穷举思想,及对于一些复杂的问题进行解析,一般采用递归,只是对一些穷举进行能优化(修枝),但是本质上还是穷举,原因是没有找到更好的方......
  • 大整数乘法-算法设计与分析
    分治法-大整数乘法输入:正负零不限,两数长度也不限。输入完第一个数后,回车,输入第二个数,回车。输出:两个数相乘的结果实现思路1.用C++实现大整数乘法2.算法性能优化对......
  • Bellman_ford和spfa算法
    Bellman_ford算法bellman_ford算法在要求起点到终点存在负权边,要求在指定k步(这是spfa无法替代的)bellman_ford和spfa都可以判断图中有无负权环......
  • 每日算法 230303
    每日算法230303题目1487.保证文件名唯一给你一个长度为n的字符串数组names。你将会在文件系统中创建n个文件夹:在第i分钟,新建名为names[i]的文件夹。由于两......
  • JVM系统优化实践(7):垃圾回收器与垃圾回收算法
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~上回说到了年轻代、老年代与数据计算的一个案例。接下来就先讲一讲年轻代和老年代的两个垃圾回收器:ParNew和CMS。和Serial......
  • 算法基础1.3.3高精度乘法
    前言先看高精度加法的文章,如果没有看,我把高精度加法文章中的总结前言放到这里该文章探讨的高精度代指C++中极大整数的计算,不是浮点数(y总说那个少见,不讲)。这个问题只在C......
  • J3、DenseNet算法实战与解析
    ......
  • 代码随想录算法训练营Day31 贪心算法| 理论基础 455.分发饼干 376. 摆动序列 53. 最
    代码随想录算法训练营理论基础什么是贪心贪心的本质是选择每一阶段的局部最优,从而达到全局最优。每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。贪......