Say you have an array for which the ith element is the price of a given stock on day i.数组
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.优化
Given an example [3,2,3,1,2], return 1code
只有一次交易,那么将prices[]数组循环一次,每次循环更新prices[]
历史最小值,并与当日价格相减获得当日利润,同步更新profit最大值。ip
public class Solution { public int maxProfit(int[] prices) { if (prices == null || prices.length == 0) return 0; int profit = 0; int min = prices[0]; for (int i = 1; i < prices.length; i++) { min = Math.min(min, prices[i]); profit = Math.max(prices[i] - min, profit); } return profit; } }
Say you have an array for which the i
th element is the price of a given stock on day i.element
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).同步
Given an example [2,1,2,0,1], return 2it
能够有无限次交易,那么在全部股票上涨的区间都进行交易。io
class Solution { public int maxProfit(int[] prices) { if (prices == null || prices.length == 0) return 0; int profit = 0; for (int i = 1; i < prices.length; i++) { profit += prices[i] > prices[i-1] ? prices[i] - prices[i-1] : 0; } return profit; } }
Say you have an array for which the ith element is the price of a given stock on day i.class
Design an algorithm to find the maximum profit. You may complete at most two transactions.循环
Given an example [4,4,6,1,1,4,2,5], return 6.
买卖股票III有几个值得注意的地方,首先left[0]
, right[len-1]
在循环以前会自动赋0。其二,是分配left[]
和right[]
的空间都要比prices.length
大1。
这道题使用双向动态规划的作法,从prices[0]
向右找prices[i]
以左的最大收益left[i]
,从prices[len-1]
向左找prices[i]
以右的最大收益right[i]
。
最后遍历全部left[i] + right[i]
,获得收益最大值。
class Solution { public int maxProfit(int[] prices) { int len = prices.length; if (prices == null || len == 0) return 0; int[] left = new int[len+1]; int[] right = new int[len+1]; int min = prices[0]; int max = prices[len-1]; int profit = 0; for (int i = 1; i < len; i++) { min = Math.min(prices[i], min); left[i] = Math.max(prices[i] - min, left[i-1]); } for (int i = len - 2; i >= 0; i--) { max = Math.max(prices[i], max); right[i] = Math.max(right[i+1], max - prices[i]); } for (int i = 0; i < len; i++) { profit = Math.max(profit, left[i] + right[i]); } return profit; } }
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.
Given prices = [4,4,6,1,1,4,2,5], and k = 2, return 6.
首先分析k与len的关系,若是k > len / 2
,至关于比每两天交易一次(昨天买今天卖,明天买后天卖)还要多,那么就存在在同一天买入并卖出的状况。那么就至关于股票交易II中的作法,在全部上涨的状况下都作了交易,返回sum
。
而后分析非上述状况的k
值:创建两个数组,数组local[i][j]
表示在第i
天正好作完第j
次交易的收益,数组global[i][j]
表示在第i
天已经作完第j
次交易的收益。
global[i][j]
是二次优化收益,以前作过的交易总数可能等于j,也可能大于j。
local[i][j]
是当次优化收益,分为两种状况:i-1
天作j-1
次交易的二次优化收益global[i-1][j-1]
,加上一次优化交易的利润:取第i-1天买入、第i天卖出的利润和0的较大者(0表示今日买入并卖出的状况),以达成第j
次交易;i-1
天作j
次交易的当次优化收益local[i-1][j]
,加上一次等效交易的利润:即第i-1
天完成j
次交易等效于第i
天完成j
次交易的状况:假设第i
天股票价格继续上涨,就至关于第i-1
天卖出后继续买入,第i
天又卖出,至关于第i-1
天没有交易操做,第i
天卖出才完成了第j
次交易。local[i][j]
最后取上述两种状况的较大值。
class Solution { public int maxProfit(int k, int[] prices) { int len = prices.length; if (prices == null || len == 0) return 0; if (k + k > len) { int sum = 0; for (int i = 1; i < len; i++) { sum += prices[i] > prices[i-1] ? prices[i] - prices[i-1] : 0; } return sum; } 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[len-1][k]; } }
public class Solution { public int maxProfit(int k, int[] prices) { int n = prices.length; if (n < 2) return 0; if (k + k > n) { int profit = 0; for (int i = 1; i < n; i++) if (prices[i] > prices[i-1]) profit += prices[i] - prices[i-1]; return profit; } int[][] dp = new int[k+1][n]; for (int i = 1; i <= k; i++) { int max = -prices[0]; for (int j = 1; j < n; j++) { dp[i][j] = Math.max(dp[i][j-1], prices[j]+max); max = Math.max(max, dp[i-1][j]-prices[j]); } } return dp[k][n-1]; } }