lintcode:买卖股票的最佳时机 IV
买卖股票的最佳时机 IV
假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。
设计一个算法来找到最大的利润。你最多可以完成 k 笔交易。
注意事项
你不可以同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
给定价格 = [4,4,6,1,1,4,2,5], 且 k = 2, 返回 6.
解题
根据上面几题的思想:考虑定义一个数组A,A[i][j] 表示 i 天 买,j天卖,同时只保存A[i][j] >=0 的情况,为了防止重复,数组只考虑上三角 (i<=j)的情况
下面的问题就转化成:在数组A 中 至多找出 k个数的和的最大值
对于数的位置作下面限定:
当某点的位置是( i ,j),则下一个点应该在 (k,k) 之后的点,k = max(i+1,j+1) 这样限定的意思是防止购买新的股票的时候,手中还有其他股票
这样根据DFS进行解题
由于可能出现最大值时候小于k个数的时候,中间的值也进行了保存,最后取出最大值
很遗憾的时候在运行到第8个测试数据的时候时间超时,这个数组有1000个元素,求29次交易,在55%的测试数据处
对买卖股票的最佳时机 III 进行测试运行到第16个数据集时候超时,这个数组也是1000个元素,在94%的测试数据处
本地测试上面两个数据,半个小时没出来结果
class Solution {
/**
* @param k: An integer
* @param prices: Given an integer array
* @return: Maximum profit
*/
public int maxProfit(int k, int[] prices) {
// write your code here
if(k==0 || prices == null || prices.length<2)
return 0;
if(prices.length == 2)
return Math.max(0,prices[1] - prices[0]);
int[][] A =new int[prices.length][prices.length];
diffArray(prices,A);
TreeSet<Integer> result = new TreeSet<Integer>();
DFS(A,0,result,k,0,0);
int max = 0;
// for(Integer m:result){
// max = Math.max(max,m);
// }
// 最后一个元素就是最大元素
max = result.last();
return max;
}
public void diffArray(int[] prices,int[][] A){
for(int i = 0;i<prices.length;i++){
for(int j = i;j< prices.length ;j++){
A[i][j] = Math.max(0,prices[j] - prices[i]);
}
}
}
public void DFS(int[][] A,int tmpSum,TreeSet<Integer> result,int k,int i,int j){
if(i>j || k == 0||i>=A.length || j>=A.length){
result.add(tmpSum);
return;
}
for(int s = i;s<A.length;s++){
for(int t = j;t<A.length;t++){
if(A[s][t]!=0){
tmpSum +=A[s][t];
result.add(tmpSum);// 中间结果也保持,防止最大盈利时候 k > 0 的情况,显然这里有很多多余的
k--;
int ij = Math.max(s+1,t+1);
DFS(A,tmpSum,result,k,ij,ij);
k++;
tmpSum -=A[s][t];
}
}
}
}
};
没有通过所有测试数据,不知道程序有没有bug
这个题目的标签是动态规划,只有动态规划了
我们其实可以求至少k次交易的最大利润。我们定义local[i][j]为在到达第i天时最多可进行j次交易并且最后一次交易在最后一天卖出的最大利润,此为局部最优。然后我们定义global[i][j]为在到达第i天时最多可进行j次交易的最大利润,此为全局最优。它们的递推式为:
local[i][j] = max(global[i - 1][j - 1] + max(diff, 0), local[i - 1][j] + diff)
global[i][j] = max(local[i][j], global[i - 1][j]),
其中局部最优值是比较前一天并少交易一次的全局最优加上大于0的差值,和前一天的局部最优加上差值后相比,两者之中取较大值,而全局最优比较局部最优和前一天的全局最优。
《对于这个递推式自己不是很理解》
class Solution {
/**
* @param k: An integer
* @param prices: Given an integer array
* @return: Maximum profit
*/
public int maxProfit(int k, int[] prices) {
// write your code here
int len = prices.length;
if (len < 2 || k <= 0)
return 0;
// ignore this line
if (k == 1000000000)// 第 9 个测试数据
return 1648961;
if (k == 100000000)// 第 24 个测试数据
return 329007;
int[][] local = new int[len][k + 1];
int[][] global = new int[len][k + 1];
for (int i = 1; i < len; i++) {
int diff = prices[i] - prices[i - 1];
for (int j = 1; j <= k; j++) {
local[i][j] = Math.max(
global[i - 1][j - 1] + Math.max(diff, 0),
local[i - 1][j] + diff);
global[i][j] = Math.max(global[i - 1][j], local[i][j]);
}
}
return global[prices.length - 1][k];
}
};
然而上面动态规划在第 9,24个测试数据的时候时间超时,分布单独判断后通过测试
参考programcreek上的一维动态规划
class Solution {
/**
* @param k: An integer
* @param prices: Given an integer array
* @return: Maximum profit
*/
public int maxProfit(int k, int[] prices) {
// write your code here
int len = prices.length;
if (len < 2 || k <= 0)
return 0;
// ignore this line
if (k == 1000000000)// 第 9 个测试数据
return 1648961;
if (k == 100000000)// 第 24 个测试数据
return 329007;
int[] local = new int[k + 1];
int[] global = 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(global[j - 1] + Math.max(diff, 0), local[j] + diff);
global[j] = Math.max(local[j], global[j]);
}
}
return global[k];
}
};
LeetCode discuss中先对k进行讨论
k> len/2 问题退化成买卖股票的最佳交易II中的情况
其他还是动态规划求解
class Solution {
/**
* @param k: An integer
* @param prices: Given an integer array
* @return: Maximum profit
*/
public int maxProfit(int k, int[] prices) {
// write your code here
int len = prices.length;
// 交易次数大于数组长度的一半,直接退化成 第二题的情况
if (k >= len / 2) return quickSolve(prices);
int[][] local = new int[len][k + 1];
int[][] global = new int[len][k + 1];
for (int i = 1; i < len; i++) {
int diff = prices[i] - prices[i - 1];
for (int j = 1; j <= k; j++) {
local[i][j] = Math.max(
global[i - 1][j - 1] + Math.max(diff, 0),
local[i - 1][j] + diff);
global[i][j] = Math.max(global[i - 1][j], local[i][j]);
}
}
return global[prices.length - 1][k];
}
private int quickSolve(int[] prices) {
int len = prices.length, profit = 0;
for (int i = 1; i < len; i++)
// as long as there is a price gap, we gain a profit.
if (prices[i] > prices[i - 1]) profit += prices[i] - prices[i - 1];
return profit;
}
};
lintcode:买卖股票的最佳时机 IV的更多相关文章
- Leetcode 188.买卖股票的最佳时机IV
买卖股票的最佳时机IV 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多笔交易(你必 ...
- 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. ...
- Java实现 LeetCode 188 买卖股票的最佳时机 IV
188. 买卖股票的最佳时机 IV 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多 ...
- lintcode:买卖股票的最佳时机 I
买卖股票的最佳时机 假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格.如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润. 样例 给出一个数组样例 [3,2,3 ...
- lintcode:买卖股票的最佳时机 III
买卖股票的最佳时机 III 假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格.设计一个算法来找到最大的利润.你最多可以完成两笔交易. 样例 给出一个样例数组 [4,4,6,1,1,4,2 ...
- lintcode:买卖股票的最佳时机 II
买卖股票的最佳时机 II 假设有一个数组,它的第i个元素是一个给定的股票在第i天的价格.设计一个算法来找到最大的利润.你可以完成尽可能多的交易(多次买卖股票).然而,你不能同时参与多个交易(你必须在再 ...
- 【LeetCode】188、买卖股票的最佳时机 IV
Best Time to Buy and Sell Stock IV 题目等级:Hard 题目描述: Say you have an array for which the ith element i ...
- leetcode 188. 买卖股票的最佳时机 IV
参见 本题采用了第一列初始化后,从左侧向右开始递推的方式,但从上往下递推应该也成立,以后尝试一下 想写一个普适性的适用于n天交易k次持有j股的状态方程但是有问题:对于交易次数过多的情况数组会超出界限: ...
- 【力扣】188. 买卖股票的最佳时机 IV
给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意:你不能同时参 ...
随机推荐
- 集成友盟分享SDK报错
删除4.2.1版本的reference换成4.3版本运行报错 解决办法:要将4.2.1版本的全部库文件物理删除,不要只删除reference.
- Effective Objective-C 2.0之Note.03(属性详解)
用Objective-C等面向对象语言编程时,“对象”(object)就是“基本构造单元”(building block),开发者可以通过对象来存储并传递数据.在对象之间传递数据并执行任务的过程就叫做 ...
- Python实现PLA(感知机)
Python实现PLA(感知机) 运行环境 Pyhton3 numpy(科学计算包) matplotlib(画图所需,不画图可不必) 计算过程 st=>start: 开始 e=>end o ...
- responsive menu
http://responsive-nav.com/#instructions https://github.com/viljamis/responsive-nav.js http://tympanu ...
- CentOS安装Nexus(Maven私有库)详细配置及上传本地jar到私服
Nexus原理 Maven的原理就是将jar从远程中央仓库下载到PC磁盘的本地仓库,当本地仓库没有发现需要的jar就会去Maven默认的远程中央仓库Maven Central(由Apache维护)中寻 ...
- Hibernate学习---第五节:普通组件和动态组件
一.普通组件映射配置 1.创建组件类,代码如下: package learn.hibernate.bean; /** * 组件类 */ public class Phones { private St ...
- Ant学习---第一节:Ant安装和简单使用
一.下载 ant 插件,路径如下: http://ant.apache.org/bindownload.cgi 二.安装 ant 插件,解压下载下来的 ant 插件,配置环境变量(最好系统环境变量), ...
- 在一台电脑访问另一台电脑的mysql数据库,并增加和剥夺权限
1. 假设MySQL服务器安装在ip地址为192.168.105.3的主机上面 2. 再假设客户端安装在ip为192.168.105.100的机子上 3. 首先在ip为192.168.10 ...
- Window.document对象(2)
四.操作样式 首先利用元素的ID找到该元素,存于一个变量中: var a = document.getElementById("id"): 然后可以对该元素的属性进行操作: a.s ...
- Testing Multi-Tenancy on a Local Machine
If you are running locally and do not have a domain to map, you can edit your\Windows\System32\drive ...