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 ...
随机推荐
- 在SQL Server里禁用聚集索引——真的好么?
有人问了我一个最有意思的问题:“你能禁用聚集索引么?” 对这个问题,我先是吓了一跳,因为我从未想过禁用聚集索引,因为聚集索引代表表数据,对这个最有趣问题,我立即答道:“我认为可以,但是...” 好吧, ...
- C#中方法的声明
C#中方法的声明(四要素) 访问修饰符 :public,private(方法的默认访问修饰符) 返回值类型:void 和 非void 方法名称 : 规范是方法名称取动词,每个单词的首字母大写. ...
- ADO.NET基础03
数据库和VS的连接,实现数据的同步,让用户的一切信息都可以在数据库中留下记录. ADO.NET基础 它是连接所有数据库的一种特殊的技术,提供对不同的数据库统一操作接口. 在VS中也可以添加数 ...
- 模拟 --- hdu 12878 : Fun With Fractions
Fun With Fractions Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit ...
- node.js中使用https请求报CERT_UNTRUSTED的问题解决
只要调用了没有受信的https就会报错:CERT_UNTRUSTED 简单的解决方法就是设置环境变量回避非授信证书的问题. 只要在请求的代码之前加上如下代码即可: process.env.NODE_T ...
- Xamarin.ios——First APP
环境:MAC+Xamarin Studio 先讲讲安装吧,最普遍的方法就是去Xamarin官网,注册个账号,填写信息啥的开始下载,安装.但,在天朝的网络环境下,在下载android模块的东东时,总会下 ...
- Java工程图标前面的红色叹号
有时Java工程图标前面会出现一个红色的叹号,这是因为工程引入的jar包不存在(或者被删除.移动)造成的. 右键点击工程,选择Build Path->Configure Build Path,弹 ...
- 从零开始学Python第0周:Python基本介绍(部分内容来源于网络)
Python入门介绍 一,Python的基本介绍 (1)概要 Python是一种解释型,面向对象,动态数据类型的高级程序设计语言.常被广泛用于处理系统管理任务和web编程.现如今Python已经成为了 ...
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D】---暑假三校训练
2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest D Problem D. Distribution in Metagonia Input ...
- POJ 1061 青蛙的约会 扩展欧几里得
扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cs ...