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 笔交易. 注意:你不能同时参 ...
随机推荐
- IOS内存管理「3」- 自动释放的基本概念和用法
- APP_Store - 怎样为iOS8应用制作预览视频
关于iOS 8应用预览视频的话题,从设计.技术规范,到录屏.编辑工具,介绍的都比较详尽:建议收藏,在接下来用的到的时候作以参考.下面进入译文. 最近一两个月里,苹果的世界里出现了很多新东西,比如屏幕更 ...
- Entity Framework 学习第二天
今天记录的内容不多,只是简单用一下Model first,新建项目,然后添加新建项,选择数据中的ado.net实体数据模型 这次我们选择空模型,然后右键,新增,实体 在这项demo中我打算建两个数据实 ...
- LintCode-Serialization and Deserialization Of Binary Tree
Design an algorithm and write code to serialize and deserialize a binary tree. Writing the tree to a ...
- Daily Scrum3
今天我们小组开会内容分为以下部分: part 1: 汇报之前分配的任务进度: part 2:分配明天的任务. ◆Part 1 组员进度报告 彭佟小组完成的优化目标: 关于软件防滥用及垃圾信息拦 ...
- 大作业NABC分析结果
大作业NABC分析结果 这次的大作业计划制作一款关于七巧板的游戏软件.关于编写的APP的NABC需求分析: N:需求 ,本款软件主要面向一些在校的大学生,他们在校空闲时间比较多,而且热衷于一些益智类游 ...
- 如何让Asp.net Web Api全局预防Xss攻击
一.概述 二.什么是XSS 三.预防方法 四.在WebApi中如何实现 在实现之前,需要了解ASP.NET WEB API的pipeline机制. 如上,可以采用多种方式进行参数的过滤 1.重写Del ...
- Google Guava学习笔记——基础工具类Joiner的使用
Guava 中有一些基础的工具类,如下所列: 1,Joiner 类:根据给定的分隔符把字符串连接到一起.MapJoiner 执行相同的操作,但是针对 Map 的 key 和 value. 2,Spli ...
- 浅谈IT
在没有学计算机应用技术之前我对IT的认知度几乎为零,曾经还天真的认为IT就是白领,只要做上IT行业,以后便可高枕无忧.后来阴差阳错学了这个专业.通过一年的学习,虽然学艺不精但多少对IT行业了解的一知半 ...
- ZOJ 3941 Kpop Music Party 贪心
题目链接: http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3941 题解: 先吧所给的区间合并,得到若干个独立的区间. 然后从左 ...