参见

本题采用了第一列初始化后,从左侧向右开始递推的方式,但从上往下递推应该也成立,以后尝试一下

想写一个普适性的适用于n天交易k次持有j股的状态方程但是有问题;对于交易次数过多的情况数组会超出界限:

测试数据:100
[106,373,495,46,359,919,906,440,783,583,784,73,238,701,972,308,165,774,990,675,737,990,713,157,211,880,961,132,980,136,285,239,628,221,948,939,28,541,414,180,171,640,297,873,59,814,832,611,868,633,101,67,396,264,445,548,257,656,624,71,607,67,836,14,373,205,434,203,661,793,45,623,140,67,177,885,155,764,363,269,599,32,228,111,102,565,918,592,604,244,982,533,781,604,115,429,33,894,778,885,145,888,577,275,644,824,277,302,182,94,479,563,52,771,544,794,964,827,744,366,548,761,477,434,999,86,1000,5,99,311,346,609,778,937,372,793,754,191,592,860,748,297,610,386,146,220,7,113,657,438,482,700,158,884,877,964,777,139,809,489,383,92,581,970,899,947,864,443,490,825,674,906,402,270,416,611,949,476,775,899,837,796,227,232,226,11,266,889,215,6,182,430,5,706,994,128,359,841,439,263,491,689,638,485,763,695,135,800,763,54,569,387,112,316,193,675,546,531,954,571,208,282,557,892,469,875,765,592,374,276,892,843,625,180,249,292,477,882,837,112,46,667,187,93,418,790,903,12,978,510,647,446,597,958,678,897,420]

时间复杂度O(n*k)空间复杂度O(n*k*2) k过大时空间超出,而且貌似这个代码是有问题的,因此先留待修改;

class Solution {
public:
int maxProfit(int K, vector<int>& prices) {
//使用MP[i][k][j]作为状态数组,i代表第i天,k代表第k次交易,j值为0(未持有股票)和1(持有股票)
int l=prices.size();
if(l<=) return ;
int res=;
int MP[l][K+][];
//状态数组初始化
for(int i=;i<l;i++){
MP[i][][]=;//0次交易却持有股票
MP[i][][]=;
MP[i][][]=;//不持有股票却有1次交易
MP[i][][]=-prices[i];
}
for(int k=;k<=K;k++){
MP[][k][]=;//第一天有k笔交易不持有股票
MP[][k][]=;//第一天有k笔交易持有股票
}
//状态转移
for(int i=;i<l;i++){
cout<<"i="<<i<<": ";
for(int k=;k<=K;k++){
MP[i][k][]=max(MP[i-][k][],MP[i-][k][]+prices[i]);
MP[i][k][]=max(MP[i-][k][],MP[i-][k-][]-prices[i]);
cout<<"("<<MP[i][k][]<<","<<MP[i][k][]<<"),";
if(MP[i][k][]>res) res=MP[i][k][];
}
cout<<endl;
}
return res;
}
};

那么针对leetcode188怎么优化空间复杂度呢,可以尝试去掉k这个维度来建立dp数组,为了明确意义,j维度也可以去掉,转而建立两个n维数组sell,buy来进行尝试

基于123的2次交易采用k维数组储存状态O(n*k)时间,O(k)空间,结果超时,k量级(10^10)超时,超空间,代码如下:

class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int len=prices.size();
if(len<=||k<=) return ;
int res=;
vector<int> buy(k,INT_MIN);
vector<int> sell(k,); for(int price:prices){
for(int i=;i<k;i++){
if(i==)
buy[]=max(buy[],-price);
else
buy[i]=max(buy[i],sell[i-]-price);
sell[i]=max(sell[i],buy[i]+price);
}
}
return sell[k-];
}
};

基于leetcode122和123的结果:由于188交易次数过多时会极大的提升空间复杂度,因此考虑以下情况,当交易次数k>len/2时题目退化为122所以整体时间复杂度上限为1/2*n^2,消除了最坏情况下交易次数过多的case,beat95%,C++代码如下:

//从第0天之前开始初始化为-∞的buy和为0的sell

class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int len=prices.size();
if(len<=||k<=) return ;
if(k>=len/) return maxProfit122(prices);
int res=;
vector<int> buy(k,INT_MIN);
vector<int> sell(k,); for(int price:prices){
buy[]=max(buy[],-price);
sell[]=max(sell[],buy[]+price);
for(int i=;i<k;i++){
buy[i]=max(buy[i],sell[i-]-price);
sell[i]=max(sell[i],buy[i]+price);
}
}
return sell[k-];
}
int maxProfit122(vector<int>& prices){
int len=prices.size();
int res=;
for(int i=;i<len;i++){
if(prices[i]>prices[i-]) res+=prices[i]-prices[i-];
}
return res;
}
};

或者直接根据第一天的价格初始化buy和sell,避免价格过高或过低的异常

class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int len=prices.size();
if(len<=||k<=) return ;
if(k>=len/) return maxProfit122(prices);
int res=;
vector<int> buy(k,-prices[]);
vector<int> sell(k,);
//sell和buy的下标代表第k次交易取值为0,1,2,………,k-1
for(int i=;i<len;i++){
int price=prices[i];
buy[]=max(buy[],-price);//第i天第0次购买的股票是前i天(包括第i天)中价格最低的股票
sell[]=max(sell[],buy[]+price);//前i天买入并卖出一次(第0次)获得的最大收益
for(int j=;j<k;j++){
buy[j]=max(buy[j],sell[j-]-price);//第i天第j次买入是i-1天以前买入j次和i天前卖出j-1次并第j天买入的比较
sell[j]=max(sell[j],buy[j]+price);//前i-1天买卖j次,和前i天买入第i天卖出的比较
}
}
return sell[k-];
}
int maxProfit122(vector<int>& prices){
int len=prices.size();
int res=;
for(int i=;i<len;i++){
if(prices[i]>prices[i-]) res+=prices[i]-prices[i-];
}
return res;
}
};

leetcode 188. 买卖股票的最佳时机 IV的更多相关文章

  1. Java实现 LeetCode 188 买卖股票的最佳时机 IV

    188. 买卖股票的最佳时机 IV 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多 ...

  2. Leetcode 188.买卖股票的最佳时机IV

    买卖股票的最佳时机IV 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多笔交易(你必 ...

  3. Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV)

    Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV) 股票问题: 121. 买卖股票的最佳时机 122. ...

  4. 【力扣】188. 买卖股票的最佳时机 IV

    给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意:你不能同时参 ...

  5. [Leetcode][动态规划] 买卖股票的最佳时机IV

    一.题目描述 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多笔交易(你必须在再次购 ...

  6. LeetCode《买卖股票的最佳时机》系列题目,最详解

    目录 说在前面 引例:只能交易一次 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 无限制买卖 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 交易 2 次,最大利润? 一.动态数 ...

  7. lintcode:买卖股票的最佳时机 IV

    买卖股票的最佳时机 IV 假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格. 设计一个算法来找到最大的利润.你最多可以完成 k 笔交易. 注意事项 你不可以同时参与多笔交易(你必须在再次 ...

  8. 每日一题-——LeetCode(121)买卖股票的最佳时机

    题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格.如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润.注意你不能在买入股票前卖出股票 ...

  9. Leetcode——121. 买卖股票的最佳时机

    题目描述:买卖股票的最佳时机 题目要求求解能获得最大利润的方式? 可以定一个二维数组 d [ len ] [ 2 ] ,其中d[ i ][ 0 ] 表示前i天可以获得的最大利润:d[ i ][ 1 ] ...

随机推荐

  1. 什么是DDoS攻击?

    本文转载自知道创宇云安全的知乎回答:DDoS 的肉鸡都是哪来的? 说到DDoS攻击,我们就不得不说“肉鸡”. “肉鸡”可谓是DDoS攻击的核心大杀器,作为一个要发起DDoS攻击的黑客来说,没有肉鸡就是 ...

  2. 安装MySQL数据库并开启远程访问

    一.安装MySQL数据库 MySQL安装在系统盘下(C:\Program Files),方便系统备份. 1.双击安装程序,勾选“I accept the license terms”,点击“Next” ...

  3. 4.pca与梯度上升法

    (一)什么是pca pca,也就是主成分分析法(principal component analysis),主要是用来对数据集进行降维处理.举个最简单的例子,我要根据姓名.年龄.头发的长度.身高.体重 ...

  4. 小米Air安装Arch Linux之图形界面配置(Gnome 和 sway)持续更新中……

    0. 前言 上一篇文章简单讲述了在小米Air上安装Arch Linux的经验,但是安装完后基本系统后,还需要额外的配置才能进到日常使用.下文简单列举一些步骤. 1. 参考网站 主要还是参考ARCH W ...

  5. CVE漏洞分析

    分析cve-2018-9489漏洞和download content provider(CVE-2018-9468, CVE-2018-9493, CVE-2018-9546), 每人至少选择一个漏洞 ...

  6. redis的数据类型和基本操作

    Redis 的Key Redis 的 key 是字符串类型,但是 key 中不能包括边界字符,由于 key 不是 binary safe的字符串,所以像"my key"和" ...

  7. inode,软硬链接

    如何查看inode ll -di /boot / /app查看文件和文件夹的inode号 df -i查看挂载点文件夹的inode号 做inode增长实验 创建60万个文件的方法1(效率不高):for ...

  8. Http请求Response Code含义

    http状态返回代码 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码.100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分.101 ...

  9. 洛谷P3402 可持久化并查集

    n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 说是可持久化并查集,实际上是 ...

  10. JAVA笔记2-面向对象与内存解析

    1.java中的变量先声明.再赋值.再使用.(局部变量必须初始化,成员变量默认初始化) 2.基本类型之外的所有类型都是引用类型.基本类型占一块内存,引用类型占两块(所有new出来的东西装在堆内存,因为 ...