买卖股票算法题的后续!
之前我们介绍了买卖股票的前三道题目:如何买卖股票?不要慌,我有妙招!没想到188题还有第四道题目,这道题目的介绍如下:
这道题是股票系列的第四题,在第三题的基础上变成了我们最多可以进行N次交易,本题的解法也适用于第三题,只需要将N设置为2就行了嘛。
首先,我们要确定的是,买和卖才算一次交易,而单独的买或者单独的卖不算一次交易。基于这个假定,如果k大于时间长度的一半的话,我们只需要简单的遍历数组,将第二天价格比前一天大的价格的差值累积求和就可以啦。
如果不是这样的话,我们在N天中进行K次交易有多种选择的话,我们可以维护两个数组,分别叫做global和local,我们用二维的数组来进行介绍,但是实际实现时可以使用一维的数组,因为我们是按天迭代的,类似这种情况的我们都可以将二维数组压缩成一维数组来减小空间复杂度。我们首先介绍一下两个数组的含义。 global[i][j]的含义是:在第I天最多进行j次交易,那么所能得到的最大的利润是什么。 local[i][j]的含义是:在第I天最多进行j次交易,并且最后一次交易是发生在第i天时所能得到的最好的利润。
根据这两个数组的含义,我们来讲解一下二者的递推公式,首先我们定义prices[i]-prices[i-1]即两天股票的差值为diff。那么对于global来说,global[i][j] = max(global[i-1][j],local[I][j]),即在最多进行j笔交易的情况下,最后一笔交易是否发生在今天,如果发生在今天所能获得的利润大的话,那么global[i][j] = local[i][j],如果不是的话,则global[i][j]=global[i-1][j]。对于local来说,local[i][j] = max(local[i-1][j] + diff, global[i-1][j-1]+diff)。也就是看两个量,第一个是全局到i-1天进行j-1次交易,然后加上今天的交易,第二个量则是取local第i-1天j次交易,然后加上今天的差值(这里因为local[i-1][j]包含第i-1天卖出的交易,所以现在变成第i天卖出,并不会增加交易次数,而且这里无论diff是不是大于0都一定要加上,因为否则就不满足local[i][j]必须在最后一天卖出的条件了)。
好了,明确了上面的递推关系,我们可以写出如下的代码:
class Solution {
public int maxProfit(int k, int[] prices) {
if(prices==null || prices.length==0 || k<=0)
return 0;
int res = 0;
if(k>=prices.length / 2){
for(int i=0;i<prices.length-1;i++)
if(prices[i+1] > prices[I])
res += (prices[i+1] - prices[I]);
}
else{
int[] global = new int[k+1];
int[] local = new int[k+1];
for(int i=0;i<prices.length-1;i++){
int diff = prices[i+1] - prices[I];
for(int j=k;j>=1;j--){
local[j] = Math.max(local[j] + diff,global[j-1] + diff);
global[j] = Math.max(local[j],global[j]);
}
}
res = global[k];
}
return res;
}
}
- 特性分支与特性开关哪家强?
- Android快速开发框架 roboguice
- 悄悄的干活,打枪的不要!勒索+比特币挖矿木马
- 拥有可移动头像的折叠Android工具栏:CollapsingAvatarToolbar
- Android平台下的第一个Tor木马
- 利用代码实现自定义圆角+阴影按钮 android-flat-button
- 周末阅读:程序员的《权利法案》
- 对利用Adobe 0day – CVE-2014-0502进行攻击的行为分析
- Android系统更改状态栏字体颜色
- Android实现竖着的滑动刻度尺效果,选择身高(竖向的)
- DedeCMS全版本通杀SQL注入漏洞利用代码及工具
- Android实现滑动刻度尺效果,选择身高体重和生日
- 浅谈开源web程序后台的安全性
- Web漏洞演练平台 – ZVulDrill
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【python设计模式-创建型】工厂方法模式
- 【python设计模式-创建型】抽象工厂模式
- 【原创】MySQL数据库开发中的6个“避免”
- mysql 中的innoDB 引擎的B+树索引
- TypeScript手记(二)
- c语言之指针运算
- MySQL online DDL 更改Varchar的字段长度
- 【python-leetcode206-翻转链表】反转链表
- 程序員必須知道的面向对象设计六大原则
- python之面向对象中的多态
- TypeScript手记(三)
- python之单例设计模式
- 【python设计模式-创建型】单例模式
- TypeScript手记(四)
- Java8使用CompletableFuture的部分方法