leetcode 第188题,我的解法,Best Time to Buy and Sell Stock IV
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">leetcode第188题,Best Time to Buy and Sell Stock IV题目如下:</span>
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most k transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
int maxProfit(int k, int prices[], int n)
对题目的分析
思路分析
- 第一种情况:s(i)<B<S<b(i+1) 这种情况下,在s(i)时刻,股票仍然在市场上,在B时刻,买入股票,在S时刻卖出股票。因此B和S一定是在(s(i),b(i+1))中满足B<S且p[S]-p[B]最大的两个下标。
- 第二种情况:b(i)<S<B<s(i) 这种情况下,在b(i)时刻,股票在用户手中,用户在S时刻卖出股票,在B时刻买入,再次在S时刻卖出。因此B和S一定是在(b(i),s(i))中满足p[S]-p[B]最大且B>S的两个下标。
数据结构设计
struct buysells//股票在用户手中的时间段
{
//股票在beginDay最低,在endDay最高,increaseProfit = p(sellDay)-p(buyDay)
//beginDay<sellDay<buyDay<endDay
int beginDay;//用户在beginDay买入
int endDay;//用户在beginday卖出
int buyDay;//若想获得最大利润增长,需再次在buyDay买入
int sellDay;//若想获得最大利润增长,需再次在sellDay卖出
int increaseProfit;//最大的利润增长价值
};
struct freetimes//股票在市场上的时间段
{
//startDay<=buyDay<sellDay<=endDay
//profit = p(sellDay)-p(buyDay)
int startDay;//股票在市场上第一天
int endDay;//股票在市场上最后一天
int buyDay;//若想获得最大利润,需在buyDay买入
int sellDay;//若想蝴蝶最大利润,需在sellDay卖出
int profit;//用户可以获得最大利润
};
代码
struct buysells//股票在用户手中的时间段
{
//股票在beginDay最低,在endDay最高,increaseProfit = p(sellDay)-p(buyDay)
//beginDay<sellDay<buyDay<endDay
int beginDay;//用户在beginDay买入
int endDay;//用户在beginday卖出
int buyDay;//若想获得最大利润增长,需再次在buyDay买入
int sellDay;//若想获得最大利润增长,需再次在sellDay卖出
int increaseProfit;//最大的利润增长价值
};
typedef struct buysells buysell;
typedef buysell *buysellpointer; struct freetimes//股票在市场上的时间段
{
//startDay<=buyDay<sellDay<=endDay
//profit = p(sellDay)-p(buyDay)
int startDay;//股票在市场上第一天
int endDay;//股票在市场上最后一天
int buyDay;//若想获得最大利润,需在buyDay买入
int sellDay;//若想蝴蝶最大利润,需在sellDay卖出
int profit;//用户可以获得最大利润
};
typedef struct freetimes freetime;
typedef freetime * freetimepointer; //扩展数组到原来的两倍,其中*bsppNumLimit为原来的数组最大长度
//由于数组中存的是buysellpointer,因此需要指向指针的指针做为参数,buysellpointer **
void expandBSPHeap(buysellpointer **heap, int *bsppNumLimit)
{
//分配两倍的数组空间,每个数组中存放的是buysellpointer
buysellpointer* newheap = (buysellpointer*)malloc(*bsppNumLimit *2 * sizeof(buysellpointer)); for (int i = 0; i < *bsppNumLimit; i++)
{
newheap[i] = (*heap)[i];
}
free(*heap);//释放原有的buysellpointer数组
*heap = newheap;//由于需要改变heap,因此使用指针
*bsppNumLimit = *bsppNumLimit * 2;
} void insertBSP(buysellpointer BSP,buysellpointer **heap, int *length, int *bsppNumLimit)
{
if(*length == *bsppNumLimit)
expandBSPHeap(heap,bsppNumLimit); (*heap)[(*length)++] = BSP;
int index = *length-1;
buysellpointer tempBSP = BSP;
//向堆中插入元素
while (index!=0 && (*heap)[(index+1)/2-1]->increaseProfit < tempBSP->increaseProfit )
{
(*heap)[index] = (*heap)[(index+1)/2-1];
index = (index+1)/2 -1;
}
(*heap)[index] = BSP;
} void deleteBSP(buysellpointer *heap, int *length)
{
//删除最大元素
if(*length == 0)
return;
(*length)--;
free(heap[0]);//释放空间
heap[0] = heap[*length];
buysellpointer tempBSP = heap[*length];
int index = 0;
int maxChildIndex = 1;
while (maxChildIndex < *length)
{
if(maxChildIndex + 1 < *length)
if(heap[maxChildIndex+1]->increaseProfit > heap[maxChildIndex]->increaseProfit)
maxChildIndex++;
if(heap[maxChildIndex]->increaseProfit > tempBSP->increaseProfit)
{
heap[index] = heap[maxChildIndex];
heap[maxChildIndex] = tempBSP;
index = maxChildIndex;
maxChildIndex = (index+1)*2 - 1;
}
else
break;
}
} void expandFTPHeap(freetimepointer **heap, int *fppNumLimit)
{
freetimepointer* newheap = (freetimepointer*)malloc(*fppNumLimit *2 * sizeof(buysellpointer)); for (int i = 0; i < *fppNumLimit; i++)
{
newheap[i] = (*heap)[i];
}
free(*heap);
*heap = newheap;
*fppNumLimit = *fppNumLimit * 2;
} void insertFTP(freetimepointer FTP,freetimepointer **heap, int *length, int *fppNumLimit)
{
if(*length == *fppNumLimit)
expandFTPHeap(heap,fppNumLimit); (*heap)[(*length)++] = FTP;
int index = *length-1;
freetimepointer tempFTP = FTP;
while (index!=0 && (*heap)[(index+1)/2-1]->profit < tempFTP->profit )
{
(*heap)[index] = (*heap)[(index+1)/2-1];
index = (index+1)/2 -1;
}
(*heap)[index] = tempFTP;
} void deleteFTP(freetimepointer *heap, int *length)
{
if(*length == 0)
return;
(*length)--;
free(heap[0]);
heap[0] = heap[*length];
freetimepointer tempFTP = heap[*length];
int index = 0;
int maxChildIndex = 1;
while (maxChildIndex < *length)
{
if(maxChildIndex + 1 < *length)
if(heap[maxChildIndex+1]->profit > heap[maxChildIndex]->profit)
maxChildIndex++;
if(heap[maxChildIndex]->profit > tempFTP->profit)
{
heap[index] = heap[maxChildIndex];
heap[maxChildIndex] = tempFTP;
index = maxChildIndex;
maxChildIndex = (index+1)*2 - 1;
}
else
break;
}
} //找到股票在市场期间能获得的最大利润
void findmaxprofit(int prices[],freetimepointer ftp)
{
int minDay = ftp->startDay;
ftp->buyDay = minDay;
ftp->sellDay = minDay;
ftp->profit = 0;
for (int i = ftp->startDay+1; i <= ftp->endDay; i++)
{
minDay = (prices[minDay] > prices[i]) ? i : minDay;
if (prices[i] - prices[minDay] > ftp->profit)
{
ftp->buyDay = minDay;
ftp->sellDay = i;
ftp->profit = prices[i] - prices[minDay];
}
}
} //找到股票在用户手中期间能获得的最大利润增长
void findMaxIncreaseProfit(int prices[],buysellpointer bsp)
{
int maxDay = bsp->beginDay;
bsp->buyDay = maxDay;
bsp->sellDay = maxDay;
bsp->increaseProfit = 0;
for (int i = bsp->beginDay+1; i < bsp->endDay; i++)
{
maxDay = (prices[i] > prices[maxDay]) ? i : maxDay;
if (prices[maxDay] - prices[i] > bsp->increaseProfit)
{
bsp->buyDay = i;
bsp->sellDay = maxDay;
bsp->increaseProfit = prices[maxDay] - prices[i];
}
} } int maxProfit(int k, int prices[], int n) { int totalProfit=0;
int fppNumLimit = 50;
//股票在市场中的时间段组成的堆
freetimepointer *fpp= (freetimepointer*)malloc(fppNumLimit*sizeof(freetimepointer));
int fppNum = 0;
int bsppNumLimit = 50;
//股票在用户手中的时间的组成的堆
buysellpointer *bspp = (buysellpointer*)malloc(bsppNumLimit*sizeof(freetimepointer));
int bsppNum = 0;
//初始化第一个股票在市场中的时间段
fpp[0] = (freetimepointer)malloc(sizeof(freetime));
fpp[0]->startDay = 0;
fpp[0]->endDay = n-1;
findmaxprofit(prices,fpp[0]);
if(fpp[0]->profit == 0)
return 0;
fppNum++; for (int i = 0; i < k; i++)
{
int maxIncreaseProfit =0, maxProfit = 0;
if(fppNum)
maxProfit = fpp[0]->profit;
if(bsppNum)
maxIncreaseProfit = bspp[0]->increaseProfit;
if(maxIncreaseProfit == 0 && maxProfit==0)//已经没有收入增长,堆为空或者没有增长空间。
return totalProfit;
if(maxIncreaseProfit > maxProfit)//用户持有的时间段进行卖出买入
{
buysellpointer tempBSP = bspp[0];
buysellpointer tempBSP1 = NULL;
if (tempBSP->sellDay -1 > tempBSP->beginDay +1)
{
tempBSP1 = (buysellpointer)malloc(sizeof(buysell));
tempBSP1->beginDay = tempBSP->beginDay;
tempBSP1->endDay = tempBSP->sellDay;
findMaxIncreaseProfit(prices,tempBSP1);
if(tempBSP->increaseProfit == 0)
free(tempBSP1);
else
insertBSP(tempBSP1, &bspp, &bsppNum,&bsppNumLimit);
}
if(tempBSP->endDay -1 > tempBSP->buyDay+1)
{
tempBSP1 = (buysellpointer)malloc(sizeof(buysell));
tempBSP1->beginDay = tempBSP->buyDay;
tempBSP1->endDay = tempBSP->endDay;
findMaxIncreaseProfit(prices,tempBSP1);
if(tempBSP->increaseProfit == 0)
free(tempBSP1);
else
insertBSP(tempBSP1, &bspp, &bsppNum,&bsppNumLimit);
}
if(tempBSP->buyDay -1 > tempBSP->sellDay +1)
{
freetimepointer tempFTP = (freetimepointer)malloc(sizeof(freetime));
tempFTP->startDay = tempBSP->sellDay +1;
tempFTP->endDay = tempBSP->buyDay - 1;
findmaxprofit(prices, tempFTP);
if(tempFTP->profit == 0)
free(tempFTP);
else
insertFTP(tempFTP,&fpp,&fppNum,&fppNumLimit);
}
totalProfit += maxIncreaseProfit;
deleteBSP(bspp,&bsppNum);
}
else
{
freetimepointer tempFTP = fpp[0];
int buyDay = tempFTP->buyDay;
int sellDay = tempFTP->sellDay;
freetimepointer tempFTP1 = NULL;
if(buyDay > tempFTP->startDay + 1)
{
tempFTP1 = (freetimepointer)malloc(sizeof(freetime));
tempFTP1->startDay = tempFTP->startDay;
tempFTP1->endDay = buyDay -1;
findmaxprofit(prices,tempFTP1);
if(tempFTP1->profit == 0)
free(tempFTP1);
else
insertFTP(tempFTP1,&fpp,&fppNum,&fppNumLimit);
}
if(tempFTP->endDay > tempFTP->sellDay + 1)
{
tempFTP1 = (freetimepointer)malloc(sizeof(freetime));
tempFTP1->startDay = tempFTP->sellDay + 1;
tempFTP1->endDay = tempFTP->endDay;
findmaxprofit(prices,tempFTP1);
if(tempFTP1->profit == 0)
free(tempFTP1);
else
insertFTP(tempFTP1,&fpp,&fppNum,&fppNumLimit);
}
if (tempFTP->sellDay-1 > tempFTP->buyDay+1 )
{
buysellpointer tempBSP = (buysellpointer)malloc(sizeof(buysell));
tempBSP->beginDay = tempFTP->buyDay;
tempBSP->endDay = tempFTP->sellDay;
findMaxIncreaseProfit(prices,tempBSP);
if(tempBSP->increaseProfit == 0)
free(tempBSP);
else
insertBSP(tempBSP,&bspp,&bsppNum,&bsppNumLimit);
}
totalProfit += maxProfit;
deleteFTP(fpp,&fppNum);
}
}
return totalProfit;
}
总结
- 不知道数组大小的情况下或在大小为变量的情况下,可以用malloc方法分配内存,如
buysellpointer* newheap = (buysellpointer*)malloc(*bsppNumLimit *2 * sizeof(buysellpointer)); - 加强了对二重指针的理解,在我的解法中,还遇到了三层指针,如buysellpointer **heap,对指针、内存的理解更加深入了。
- 数组大小未知,可以先分配一定内存,如果不够,分配两倍内存,进行拷贝,然后返回。
- 对最大堆的插入和删除的理解深入,毕竟自己写代码。
- 不足在于代码太长,特别是两个不同类型的堆,每种操作要写两遍代码,十分不方便。shagnwang
leetcode 第188题,我的解法,Best Time to Buy and Sell Stock IV的更多相关文章
- 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. ...
- 【LeetCode】Best Time to Buy and Sell Stock IV
Best Time to Buy and Sell Stock IV Say you have an array for which the ith element is the price of a ...
- Java for LeetCode 188 Best Time to Buy and Sell Stock IV【HARD】
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- [LeetCode] 188. Best Time to Buy and Sell Stock IV 买卖股票的最佳时间 IV
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- 【LeetCode】188. Best Time to Buy and Sell Stock IV 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- [LeetCode] Best Time to Buy and Sell Stock IV 买卖股票的最佳时间之四
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- LeetCode Best Time to Buy and Sell Stock IV
原题链接在这里:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/ 题目: Say you have an array ...
- [LeetCode][Java] Best Time to Buy and Sell Stock IV
题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...
- 【刷题-LeetCode】188 Best Time to Buy and Sell Stock IV
Best Time to Buy and Sell Stock IV Say you have an array for which the i-th element is the price of ...
随机推荐
- CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins
前言 盒子模型作为CSS基础中的基础,曾一度以为掌握了IE和W3C标准下的块级盒子模型即可,但近日在学习行级盒子模型时发现原来当初是如此幼稚可笑.本文尝试全面叙述块级.行级盒子模型的特性.作为近日 ...
- 【Swift学习】Swift编程之旅---方法(十五)
在Swift中结构体和枚举也能够定义方法,而在 Objective-C 中,类是唯一能定义方法的类型. 实例方法 实例方法是属于某个特定类.结构体或者枚举类型实例的方法,实例方法提供访问和修改实例属性 ...
- 一图看懂host_only nat bridge拓扑结构
VMware三种模式 我们在使用VMware时经常能看到三种网络的连接模式:Bridged Host-Only Nat,它们都有什么作用,网络拓扑是怎样的?怎样才能让他们上网,他们相互间能不能相互访 ...
- C#开源
商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Phone-7-SDK E ...
- C语言学习012:将代码文件分成多个文件
如果将所有的代码都写到一个文件中,当对于小项目来说不会有什么问题,但是当它一个很大的工程的时候,如果将所有代码都写到一个文件中,不但开发起来很困难,维护更是头疼,所以我们应该将代码按不同的功能分别建立 ...
- 【Remoting】.Net remoting方法实现简单的在线升级(上篇:更新文件)
一.前言: 最近做一个简单的在线升级Demo,使用了微软较早的.Net Remoting技术来练手. 简单的思路就是在服务器配置一个Remoting对象,然后在客户端来执行Remoting ...
- Swift 3 迁移工作总结
写在前面 Swift 3.0 正式版发布了差不多快一个月了,断断续续的把手上和 Swift 相关的迁移到了Swift 3.0.所以写点小总结. 背景 代码量(4万行) 首先,我是今年年初才开始入手 S ...
- 判断JS对象是否拥有某属性
两种方式,但稍有区别 1.in 运算符
- 使用powerdesigner创建数据库表
(1 )新建概念模型 (2 )新建表,添加表各个属性 填写属性名称和类型,主键要勾选上P,M,D. (3) 如何各个表中有相同的字段名,需要设置Tool->Model Options,把红色区域 ...
- Response.Redirect 无法跳转页面
错误现象:Response.Redirect(Server.MapPath("BackIndex.aspx")); 打断点测试执行了这一句,Server.MapPath(" ...