[leetcode]BestTimetoBuyandSellStock买卖股票系列问题

问题1:

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.

Example 1:
Input: [7, 1, 5, 3, 6, 4]
Output: 5

max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
Example 2:
Input: [7, 6, 4, 3, 1]
Output: 0

In this case, no transaction is done, i.e. max profit = 0.
动态规划,和寻找最大子串差不多,设置三个变量,一个最小值min,一个局部解cur,一个全局解res,
* min = min(min,price[i]),cur = price[i] - min,res = max(cur,res)
* 遍历过程中不断更新三个量,最后全局解就是结果
public int maxProfit(int[] prices) {
        if (prices.length < 1)
            return 0;
        int min = prices[0];
        int res = 0;
        int cur = 0;
        for (int i = 1; i < prices.length; i++) {
            //如果当前值比最小值还小,那么更新min之后可以停止此次循环了
            if (prices[i] <= min)
            {
                min = prices[i];
                continue;
            }
            cur = prices[i] - min;
            res = Math.max(cur,res);
            }
        return res;
    }

问题2:

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).
和1不同的是这次可以多次交易了,约束条件是必须卖了才能再买(当天卖了接着买也行)
贪心算法:只需要每次考察两天的价格情况,能赚就卖,不能赚就考察接下来两天,把所有赚的钱加起来就是结果
*由于当前两天的买卖情况不会影响前后的情况,所以可以用贪心算法
public int maxProfit(int[] prices) {
        if (prices.length < 2)
            return 0;
        int sta = 0;
        int end = 1;
        int res = 0;
        while (end < prices.length)
        {
            int cur = prices[end] - prices[sta];
            if (cur > 0)
            {
                res += cur;
            }
            sta++;
            end++;
        }
        return res;
    }

问题3:

这次是可以交易任意次,但是每次卖出的时候都要收取一定费用,所以不能用贪心了,因为贪心只能考虑相邻的两个是否交易,但是这次可能出现前边的留着不卖而后边卖,要用常规的动态规划,但是状态法方程和动态变量都有两个

直接上代码

public static int maxProfit(int[] prices, int fee) {
        /*
        一开始想着用贪心算法,和之前做的那个可以多次交易的题目一样,但是试了试是不行的,因为前边买的情况对后边会产生影响
        因为这次交易有费用,不是只要有差价就卖,要选差价最大的组合卖,用动态规划
        每天都有两种状态,一种是当前持有股票,一种是没有股票,算出两种情况的最大收益情况,最后返回最后一天不持有股票的情况就是收益最大
         */
        if (prices.length==0)
            return 0;
        int[] not = new int[prices.length];
        int[] hold = new int[prices.length];
        hold[0] = -prices[0];
        for (int i = 1; i < prices.length; i++) {
            //如果今天没有持有股票,那么有两种情况,昨天有股票,今天卖了。或者昨天就没有股票,今天也没买,选收益大的。
            not[i] = Math.max(not[i-1],hold[i-1] + prices[i]-fee);
            //如果今天持有股票,那么要么是昨天就持有,今天没卖。要么昨天没有,今天买的
            hold[i] = Math.max(hold[i-1],not[i-1]-prices[i]);
        }
        return not[prices.length-1];
    }

未完待续...

原文地址:https://www.cnblogs.com/stAr-1/p/7374691.html