博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Best Time to Buy and Sell Stock III O(n) 求解方法
阅读量:4677 次
发布时间:2019-06-09

本文共 2282 字,大约阅读时间需要 7 分钟。

leetcode的题目:

leetcode的题目都很简练,但是很有趣,认真地做吧。

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 two transactions.

Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

a. 对于输入为n,最多可以买卖两次,求最大的盈利。

b. 买两次的收益通常比买一次来的大。

c. 对于输入规模为n,当n>=4时可以将n分为两部分,且分类的方法有n-3种。每份的最少个数为2。因为n个元素,总共有n-1条缝隙可以划分,又最左或最右至少要有两个元素,所以n-1-2 = n-3 种。

d. 求得划分一次(买卖两次)的每种划分的最大盈利,和不划分的最大盈利,即得到最大的盈利。

  max_profit = max{买卖两次(划分一次),买卖一次(不进行划分)}

e. 定义状态矩阵dp_be[i], 表示以0为起点,i为终点的子串的最大盈利。

dp_be[0] = 0;	int i, max_profit = 0, cur_min = prices[0];	for(i = 1; i < len; i++) {		max_profit = max(max_profit, prices[i]-cur_min);		cur_min = min(cur_min, prices[i]);		dp_be[i] = max_profit; // 在i时卖出的最大收益	}

f. 定义状态矩阵dp_af[i],表示以i为起点,n-1(最后元素)为终点的子串的最大盈利

max_profit = 0; 	int cur_max = prices[len-1];	for(i = len-2; i >= 0; i--) {		max_profit = max(max_profit, cur_max-prices[i]);		cur_max = max(cur_max, prices[i]);		dp_af[i] = max_profit;	}

g. 由此可得,对于以i为划分点,将n个元素分成两个子串,要求两个子串之和最大,根据贪心算法思想,要求每个子串都去的最大值。对i从1到n-3循环得到最大值。

// 放入只买一次的最大值		int max = dp_be[len-1];		// 在同一天卖了再买是没有意义的		// 求两个数组和的最大值		for(i = 1; i < len-1; i++) {			if(dp_be[i]+dp_af[i+1] > max)				max = dp_be[i]+dp_af[i+1];		}

主要:dp_be[i]表示0开始,i结束的子串的最大盈利,所以它对应的尾部子串为dp_af[i+1],表示以i+1开始,n-1为终点的子串的最大盈利。

h. 代码

int Solution::maxProfit2(vector
&prices) { int len = prices.size(); if(len < 2) return 0; int *dp_be = new int[len]; // 记录前向最大 int *dp_af = new int[len]; // 记录后向最大 dp_be[0] = 0; int i, max_profit = 0, cur_min = prices[0]; for(i = 1; i < len; i++) { max_profit = max(max_profit, prices[i]-cur_min); cur_min = min(cur_min, prices[i]); dp_be[i] = max_profit; // 在i时卖出的最大收益 } dp_af[len-1] = 0; max_profit = 0; int cur_max = prices[len-1]; for(i = len-3; i >= 0; i--) { max_profit = max(max_profit, cur_max-prices[i]); cur_max = max(cur_max, prices[i]); dp_af[i] = max_profit; } if(len == 2) return dp_be[len-1]; else { // 放入只买一次的最大值 int max = dp_be[len-1]; // 在同一天卖了再买是没有意义的 // 求两个数组和的最大值 for(i = 1; i < len-1; i++) { if(dp_be[i]+dp_af[i+1] > max) max = dp_be[i]+dp_af[i+1]; } return max; }}

 

i. 画个图说明以下

 

 

 

 

转载于:https://www.cnblogs.com/themo/p/3684113.html

你可能感兴趣的文章
上海秋季HCC小记
查看>>
Illustrator 上色
查看>>
truncate表恢复
查看>>
this关键字的使用
查看>>
Console.Read()、Console.ReadLine()、Console.ReadKey()
查看>>
ecere 编译过程中遇到的问题
查看>>
Cyclone V 与 Avalon-MM资料整理——DE1-SOC学习笔记(1)
查看>>
centos7 添加开机启动项
查看>>
Codeforces 346D Robot Control(01BFS)
查看>>
NHibernate.3.0.Cookbook第四章第2节的翻译
查看>>
19.C#逐一介绍IEnumerable和IEnumerable<T>中的扩展方法(10.3-10.5)
查看>>
听说最近你读过不少书
查看>>
linux之Ubuntu下Django+uWSGI+nginx部署
查看>>
【转】Struts1.x系列教程(2):简单的数据验证
查看>>
HTML head元素
查看>>
requireJS
查看>>
Poj3667Hotel线段树
查看>>
待嫁闺中:PPTV的辛酸史
查看>>
作用域
查看>>
Read
查看>>