`
ouqi
  • 浏览: 42171 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

[leetcode]Best Time to Buy and Sell Stock

 
阅读更多

Best Time to Buy and Sell Stock

Say you have an array for which the ith element is the price of a given stock on day i.

 

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

一开始思路:

对于第i天,如果选择在这一天卖出的话,考虑在什么时候买入合适? 思考发现 一定是在[0,i]范围内的价格最低的那一天买入最合适。

那我们

  1. 初始化最大利润maxProfit = 0;
  2. 遍历prices数组,过程中记录价格最小值min.当遍历到第i天的时候 min一定是在[0,i]范围内的,比较prices[i]-min和max的大小 max取两者中的最大值

ps: 期间还想过其实没必要考虑每一天卖出的情况,在一个单调序列[i,j]中 计算第i天卖出时min下标<=i;而在计算第j天卖出时 min下标同样<=i.所以第j天卖出肯定比第i天卖出利润大,遍历的时候可以直接考虑单调递增序列的尾部天数卖出。但是感觉复杂度没啥改进,还是要遍历整个数组,而且写起来更加复杂,所以想想还是之前的比较好。

 

后来想用动态规划,定义c[i]表示[0,i]范围内的maxProfit,min为[0,i-1]范围内的最小值

则有

  1. 初始c[0] = 0;
  2. 当prices[i]<min时: 即当前值比前面的最小值还要小,则c[i] = c[i-1];并且把min赋值为prices[i];
  3. 当prices[i]>=min时: c[i] = max{c[i-1],prices[i]-min};
  4. 我们要求的maxProfit = c[len-1];

后来一想似乎没必要用数组c去保存因为c[i]肯定是大于等于c[i-1]。所以用一个变量max记录就可以。然后代码写出来,发现跟最开始的思路是一样的-。-

 

 

 public int maxProfit(int[] prices) {
        // Start typing your Java solution below
        // DO NOT write main() function
          if(prices == null || prices.length == 0)  return 0;
             int len = prices.length;
	        
	         int max = 0;
	         int min = prices[0];
	         
	         for(int i = 1;i<=len-1;i++){
	             if(prices[i]<min) {min = prices[i];}
	             else max = prices[i]-min>max? prices[i]-min:max;
	         }
             return max;
    }

 

Best Time to Buy and Sell Stock II

与上题的区别在于可以交易n次,算最大利润

 

直观的想法就是在价格数组prices[]的所有单调序列的头(最低点)买入,尾(最高点)卖出;

 

然后就想有没有可能不按照上述规则算出的利润更大呢?思考了下,发现不可能

  1. 对于单调序列内部的买入卖出不难思考 ,肯定是头买入,尾卖出最高。
  2. 那考虑跨越单调序列的买入卖出:
  3.  假设[i, k]  [k+1, j] 是两个相邻的单调区间,我们在[i , k]内的某一点 x 买入,在[k+1, j ]内的某一点y卖出,首先当x  = i和y = j时,是这种买入卖出方式的最大值(因为x不等于i的话,x-1买入肯定比x买入收益更大,y的取值类似)。 那么比较在i点买入,j点卖出和在i点买入,k点卖出,k+1点买入,j点卖出的利润大小:因为分为了两个单调区间,所以price[k+1]<price[k] 根据这个条件可以证明: prices[j] - prices[i] <prices[j] - prices[k+1] + prices[k] - prices[i] 所以第二种方式i点买入,k点卖出,k+1点买入,j点卖出的利润更大。

代码:

 

  public int maxProfit(int[] prices) {
        // Start typing your Java solution below
        // DO NOT write main() function
       if(prices == null || prices.length == 0) return 0;
       int i = 0;
       int min,max;
       int maxProfit = 0;
       int len =  prices.length;
       
       while(i<=len-1){
           min = prices[i];
           max = prices[i];
           i++;
           while(i<=len-1&&prices[i]>=prices[i-1]) i++;
           max = prices[i-1];
           maxProfit = maxProfit + max - min;
       }
       return maxProfit;
    }

 

Best Time to Buy and Sell Stock III

这个的限制就是交易最多2次

刚开始就是想的先确定[0,i]范围内的maxProfit,然后算[i,len-1]范围内的maxProfit 求和,取和中的最大值。

然后就在纠结扫一遍 扫到[0,i]的时候,[0,i]范围内的maxProfit好确定,但是[i,len-1]范围内的觉得不好算。

然后发现自己脑残了...为啥一定要纠结同步确定呢,我扫两遍,第一遍从头到尾把[0,i]范围内的最大确定,像

Best Time to Buy and Sell Stock中那样记录为数组c, 第二遍从尾到头扫,在算出[i,len-1]范围内的最大值之后,直接去数组c中取出[0,i-1]范围内的就可以了...

代码:

 

  public int maxProfit(int[] prices) {
	        // Start typing your Java solution below
	        // DO NOT write main() function
	       if(prices == null || prices.length == 0)  return 0;
	         int len = prices.length;
	        
	         int c[] = new int[len];//c[i] means max in interval[0,i] 
	         c[0] = 0;
	         int min = prices[0];
	         
	         for(int i = 1;i<=len-1;i++){
	             if(prices[i]<min) {min = prices[i];c[i] =c[i-1];}
	             else c[i] = prices[i]-min>c[i-1]? prices[i]-min:c[i-1];
	         }
	         int maxProfit = c[len-1];
	         int max = 0;
	        
	        int diff = 0;
	        int tempMax = 0;
	         for(int j = len-1;j>=0;j--){
	             if(prices[j]>max) {max = prices[j];}
	             else if( max-prices[j]>diff) diff = max - prices[j];
	             if(j>=1) tempMax = diff+c[j-1];
	             if(tempMax>maxProfit) maxProfit = tempMax;
	             
	         }
	         
	         return maxProfit;   
	    }

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    MongoDB分片集群搭建教程:副本集创建与数据分片

    内容概要:本文提供了详细的MongoDB分片集群的搭建指导,涵盖了从环境准备、配置文件编写、副本集的建立、主节点的选择、配置服务器和数据分片服务器的配置到最后的路由节点的搭建与操作整个流程,以及对数据库的哈希与范围两种分片策略的应用介绍和具体命令执行。 适合人群:熟悉NoSQL数据库概念并对MongoDB有一定了解的技术人员,尤其是在大型数据管理和分布式数据库架构设计中有需求的开发者。 使用场景及目标:帮助技术人员掌握构建高效能、高可用性的MongoDB分片集群的方法,适用于处理大规模、实时性强的数据存储与读取场景。 其他说明:文中通过实例演示了每个步骤的具体操作方法,便于跟随文档实操,同时也介绍了可能遇到的问题及其解决方案,如在没有正确配置的情况下试图写入数据时出现错误等情况的处理。

    CPPC++_嵌入式硬件的物联网解决方案blinker库与Arduino ESP8266 ESP32一起工作.zip

    CPPC++_嵌入式硬件的物联网解决方案blinker库与Arduino ESP8266 ESP32一起工作

    CPPC++_逆向调用QQ Mojo IPC与WeChat XPlugin.zip

    CPPC++_逆向调用QQ Mojo IPC与WeChat XPlugin

    CPPC++_现代活动指标.zip

    CPPC++_现代活动指标

    CPPC++_Xournal是一款手写笔记软件,支持PDF注释,使用C语言编写,支持GTK3,支持Linux,如Ubu.zip

    CPPC++_Xournal是一款手写笔记软件,支持PDF注释,使用C语言编写,支持GTK3,支持Linux,如Ubu

    基于SSM学生实习管理系统前台小程序与后台管理系统开发实践

    资源概述: 本资源提供了一套完整的学生实习管理系统解决方案,涵盖了前台小程序页面与后台管理系统两大模块。前台小程序页面设计简洁直观,用户可根据不同身份(学生或企业)进行登录。学生用户能够方便地浏览并投递感兴趣的实习岗位,而企业用户则能轻松发布实习信息,吸引优秀人才。后台管理系统功能全面,包括个人中心、首页、学生管理、教师管理、企业管理、招聘管理、评分管理以及实习管理等多个方面,为管理员提供了强大的数据管理和操作工具。 技术栈亮点: SSM框架:系统后台采用Spring、Spring MVC和MyBatis Plus(简称SSM)作为核心开发框架,确保了系统的稳定性、可扩展性和可维护性。Spring作为控制反转(IoC)和面向切面编程(AOP)的容器,为系统提供了强大的业务逻辑处理能力;Spring MVC则负责处理Web请求和响应,实现了前后端的分离;MyBatis Plus作为持久层框架,简化了数据库操作,提高了开发效率。 MySQL数据库:系统采用MySQL作为数据库存储解决方案,支持大数据量的存储和高效查询。 如有侵权请联系我删除,谢谢

    微服务闪聚支付项目.zip

    微服务闪聚支付项目

    Rust 与 Java 互调实战示例

    博客链接 https://blog.csdn.net/weixin_47560078/article/details/143714557 文章从原理介绍出发,实现了 Rust 与 Java 的互调。利用 JNI 技术,可以充分发挥 Rust 的性能优势,同时保持 Java 的跨平台特性。这种技术组合适用于对性能要求较高的应用场景,如图像处理、数据分析和系统级编程等。

    CPPC++_这是我翻译的艾根中文文档.zip

    cppc++

    Matlab实现斑马优化算法ZOA-TCN-Multihead-Attention多输入单输出回归预测算法研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    Matlab实现雪融优化算法SAO-TCN-Multihead-Attention多输入单输出回归预测算法研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    分布式事务lcn.zip

    分布式事务lcn

    基于Simulink的正弦波PWM技术和三次谐波注入PWM技术研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    【风电功率预测】基于BiTCN的风电功率多变量输入预测研究附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    CPPC++_这是由一块迷你带OV2640双DRV8833驱动TypeC接口PSRAM的ESP32PicoD4开发板驱.zip

    cppc++

    JAVA安卓手机与电脑的socket通信源码数据库 其他源码类型 WinForm

    安卓手机与电脑的socket通信源码

    Anaconda:JupyterNotebook使用教程.docx

    Anaconda:JupyterNotebook使用教程.docx

    Amazon S3:S3静态网站托管教程.docx

    Amazon S3:S3静态网站托管教程.docx

    Python商品销售数据分析可视化项目源码(期末大作业).zip

    Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。 Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析

    CPPC++_wechathookWeChatApi微信Api微信hook微信接口python微信接口java微信Ap.zip

    CPPC++_wechathookWeChatApi微信Api微信hook微信接口python微信接口java微信Ap

Global site tag (gtag.js) - Google Analytics