Bsst Time to Buy and Sell Stock系列

来源:互联网 发布:win10修改无线mac地址 编辑:程序博客网 时间:2024/04/29 13:51

1: leetcode第121题 Best Time to Buy and Sell Stock

题目描述:

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.

题意是给定一个数组,数组中每个元素代表股票的价格(第i个元素代表第i天价格)。
要求:仅仅允许一轮交易(买一次、卖一次),设计一个算法,求得最大利润。

题意分析:

法1: 贪心法,分别找到价格最低和价格最高的一天,低进高出,注意,要求最低的一天要在最高的一天之前。
所以,设定一个变量,存储在今天之前的最低价格。一定要在今天之前。
法2:把原始的序列变成差分序列,最终,用最大m子段和求解,m为1.

代码:

// 法1:分别找到价格最低和价格最高的一天,低进高出。public class Solution121 {    public static int maxProfit(int[] prices) {        if (null == prices || prices.length < 2) {            return 0;        }        final int n = prices.length;         int minPrice = prices[0]; // 记录在此之前的最低价格, 非常重要        int maxProfit = 0;        // 记录到目前为止地 最大利润        for (int i = 1; i != n; ++i) {            int todayProfit = prices[i] - minPrice; // 如果今天卖出股票,能获得的最大利润是多少            // 实时更新当前利润: 如果今天卖出股票,所取得的利润比之前卖出能获得更高利润,则今日卖出            maxProfit = maxProfit > todayProfit ? maxProfit : todayProfit;            // 实时更新当前最低买入价格            minPrice = minPrice < prices[i] ? minPrice : prices[i];         }        return maxProfit;    }}

2: leetcode第122题 Best Time to Buy and Sell Stock II

题目描述:

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 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).

题意是给定一个数组,数组中每个元素代表股票的价格(第i个元素代表第i天价格)。
可以买卖任意多的次数,设计一个算法,求得最大利润。

思路分析:

只要今天的股票价格比昨天高,就可以卖出。一天之内,可以先将股票卖出,然后再买回来。
则:贪心法,低进高出,把所有的正的差价都加起来。

public class Solution122 {    public int maxProfit(int[] prices) {        if (null == prices || 0 == prices.length) {            return 0;        }        final int n = prices.length;        int maxProfit = 0;        for (int i = 1; i < n; ++i) {            // 只要当天价格比前一天高,就做一次交易,同一天可以多次交易            maxProfit += (prices[i] - prices[i - 1]) > 0 ? (prices[i] - prices[i - 1]) : 0;        }        return maxProfit;    }}

3:leetcode第123题 Best Time to Buy and Sell Stock III

题目描述:

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.

题目意思是给定一个数组,数组中的元素表示股票的价格(第i个数组表示第i天股票的价格)。现在要求你设计一个算法,这批股票,最多可以买卖两次,求最大的利润。

Note:

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

即要求在买新股票之前,必须卖掉旧的股票。

思路分析:

设状态f(i), 表示区间[0, i] (0 <= i <= n - 1)的最大利润;状态g(i),表示区间[i, n - 1] (0 <= i <= n - 1)的最大利润,则最终答案为max{f(i) + g(i)} (0 <= i <= n - 1)。

即在区间[0, i]可以买卖一轮股票,在[i, n - 1]也可以买卖一轮股票。(当然也可以任意一轮都买或不买)。两个区间最大之和。

注意,两个区间都包括了i,因为在某一天,可以先卖掉,然后再买入。

代码:

public class Solution123 {    public int maxProfit(int[] prices) {        if (null == prices || prices.length < 2) {            return 0;        }        final int n = prices.length;        // 区间[0, i]内的最大利润,所以要从前向后遍历        int[] f = new int[n]; // 前半段的利润,f[i]记录第i天能取得的最大利润。(默认初始化为0)        int minPrice = prices[0]; // 前半段从前往后遍历,所以记录今天之前的最低价格        for (int i = 1; i < n; ++i) {            int todayProfit = prices[i] - minPrice;            f[i] = f[i - 1] > todayProfit ? f[i - 1] : todayProfit;            minPrice = minPrice < prices[i] ? minPrice : prices[i];        }        // 区间[i, n - 1]的最大利润,即今天(第i天)是买入股票,后面卖的,所以要从后向前遍历。        int[] g = new int[n]; // 后半段的利润,g[i]记录第i天所能取得的最大利润(默认初始化为0)        int maxPrice = prices[n - 1]; // 记录今天之后的最大价格,以用来减去今日价格        for (int i = n - 2; i >= 0; --i) {            int todayProfit = maxPrice - prices[i];            g[i] = g[i + 1] > todayProfit ? g[i + 1] : todayProfit;            maxPrice = maxPrice > prices[i] ? maxPrice : prices[i];        }        int maxProfit = 0;        for (int i = 0; i < n; ++i) {            maxProfit = maxProfit > (f[i] + g[i]) ? maxProfit : (f[i] + g[i]);        }        return maxProfit;    }}

题目4: leetcode188 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).

给定一个数组,数组中的每个元素,代表当天股票的价格。设计一个算法,求买卖股票的最大利润。要求最多允许买卖k次。

注意: 买入股票之前,必须先将手里有的卖出去。

思路分析:

k >= n

如果k比天数n还大,那么直接求出差分数列,将所有非负数加起来就是最大利润。

k小于n。

设置两个变量global[n][k + 1]local[n][k + b1].

首先global[i][j]的表示前i天进行了j次交易(卖出j次),所取得的最大利润。即是不断地和已经计算出的local进行比较,把大的保存在global中。

然后看local,关键是要理解local的定义,local[i][j]表示,前i天进行了j次交易(卖出),并且第i天进行了第j次交易的最大利润,所以local[i][j]中必然有一次交易,也就是当近一次交易,发生在第i天。

表达式:

local[i][j]=max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff),其中diff为price[i] - price[i - 1]即今日和昨日差价。

global[i-1][j-1]+max(diff,0)为前i-1天进行j-1次交易,然后加上今天的交易(如果今天是赚钱的话那么前一天买今天买,这样就赚钱了。如果前一天买今天卖不赚钱,那么就今天买今天卖,这样就赚了0元。)

local[i-1][j]+diff则是取local第i-1天j次交易(在第i-1天卖出了股票),然后加上今天的差值(这里因为local[i-1][j]包含第i-1天卖出的交易,所以现在变成第i天卖出(即原本前i-1天交易j次,现在变成了前变成第i天卖出,注意不能变成local[i - 1][j - 1] + diff),并不会增加交易次数,而且这里无论diff是不是大于0都一定要加上,因为否则就不满足local[i][j]必须在最后一天卖出的条件了)。

global[i][j]=max(local[i][j],global[i-1][j])
local[i][j]表示前i-1天交易了j-1次,第j天交易了一次; global[i - 1][j]表示前i-1天交易了j次,第i天没有进行交易。

代码

    public int maxProfit(int k, int[] prices) {        if (null == prices || prices.length < 2) {            return 0;        }        final int n = prices.length;        if (n <= k) {            return maxProfit(prices);        }        int[][] global = new int[n][k + 1];        int[][] local = new int[n][k + 1];        for (int i = 1; i < n; ++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[n - 1][k];    }    private int maxProfit(int[] prices) {        final int n = prices.length;        int maxProfit = 0;        for (int i = 1; i < n; ++i) {            maxProfit += prices[i] > prices[i - 1] ? (prices[i] - prices[i - 1]) : 0;        }        return maxProfit;    }
0 0
原创粉丝点击