zoukankan      html  css  js  c++  java
  • stock系列 121 & 122 & 309 & 714 & 123 & 188

    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 (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

    Note that you cannot sell a stock before you buy one.

    Example 1:

    Input: [7,1,5,3,6,4]
    Output: 5
    Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 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
    Explanation: In this case, no transaction is done, i.e. max profit = 0.

    解题思路:

    最简单的版本,只允许一次交易,在每次找最小的过程中,更新可能的最大的收益。

    代码:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            int buy = INT_MAX;
            int ret = 0;
            for(int i = 0; i < prices.size(); i++){
                buy = min(buy, prices[i]);
                ret = max(ret, prices[i] - buy);
            }
            return ret;
        }
    };

    -----------------------------下一题分割线---------------------------------

    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 (i.e., buy one and sell one share of the stock multiple times).

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

    Example 1:

    Input: [7,1,5,3,6,4]
    Output: 7
    Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
                 Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
    

    Example 2:

    Input: [1,2,3,4,5]
    Output: 4
    Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
                 Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
                 engaging multiple transactions at the same time. You must sell before buying again.
    

    Example 3:

    Input: [7,6,4,3,1]
    Output: 0
    Explanation: In this case, no transaction is done, i.e. max profit = 0.

    解题思路:

    这道题一开始想复杂了,其实是简单的贪婪。

    题目要求我们只要收益最大,想买卖几次就买卖几次,但是卖要在买前面。

    所以我们只要加入 

    max(prices[i] - prices[i-1], 0);

    一开始我会想那每次相邻减的时候,不是会有重复吗?那怎么办?

    其实如果真的重复发生了,如: 1, 3, 7

    先算了3-1,又算了 7-3

    但是合起来就是7-1啊!

    买的时间为1, 卖为7!

    代码:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            if(prices.size() < 2)
                return 0;
            int ret = 0;
            for(int i = 1; i < prices.size(); i++){
                ret += max(prices[i] - prices[i-1], 0);
            }
            return ret;
        }
    };

    -------------------------我是下一题分割线----------------------------

    714. Best Time to Buy and Sell Stock with Transaction Fee

    问题描述:

    Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee.

    You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)

    Return the maximum profit you can make.

    Example 1:

    Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
    Output: 8
    Explanation: The maximum profit can be achieved by:
    • Buying at prices[0] = 1
    • Selling at prices[3] = 8
    • Buying at prices[4] = 4
    • Selling at prices[5] = 9
    The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
    

    Note:

    • 0 < prices.length <= 50000.
    • 0 < prices[i] < 50000.
    • 0 <= fee < 50000.

    解题思路:

    买卖股票时有两种状态:持股和不持股,我们可以就这两种状态寻找状态转移方程

    unhold[i] : 不持股时到第i天的最大利益

    hold[i] : 持股时到第i天的最大利益

    这样的话状态转移会有4种:

    1. 持股 -> 不持股: 说明将手上的股票卖出: unhold[i-1] + prices[i] - fee

    2. 持股 -> 持股 :   说明没有动作: hold[i] = hold[i-1]

    3. 不持股 -> 持股:  说明新购入股票:unhold[i] = unhold[i-1] - prices[i]

    4. 不持股 -> 不持股: 说明没有动作:unhold[i] = unhold[i-1]

    状态转移方程为:

    unhold[i] = max(unhold[i-1] + prices[i] - fee , unhold[i-1])

    hold[i] = max(unhold[i-1] - prices[i] , hold[i-1])

    代码:

    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            vector<int> unhold(prices.size(), 0);
            vector<int> hold(prices.size(), 0);
            hold[0] = -prices[0];
            for(int i = 1; i < prices.size(); i++){
                hold[i] = max(hold[i-1], unhold[i-1] - prices[i]);
                unhold[i] = max(hold[i-1] + prices[i] - fee, unhold[i-1]);
            }
            return unhold[prices.size() - 1];
        }
    };

    经过观察我们的状态转移只与i, i-1有关,所以我们可以用两个变量来代替

    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            int unhold = 0;
            int hold = -prices[0];
            for(int i = 1; i < prices.size(); i++){
                int temp_hold = max(hold, unhold - prices[i]);
                int temp_unhold = max(hold + prices[i] - fee, unhold);
                hold = temp_hold;
                unhold = temp_unhold;
            }
            return unhold;
        }
    };

    ---------------------------我是下一题分割线-----------------------------------

    309. Best Time to Buy and Sell Stock with Cooldown

    问题描述:

    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) with the following restrictions:

    • You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
    • After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)

    Example:

    Input: [1,2,3,0,2]
    Output: 3 
    Explanation: transactions = [buy, sell, cooldown, buy, sell]

    解题思路:

    同样将状态看为持股和不持股两种,但是此时由于多加了一个限制,状态转移方程发生改变

    这样的话状态转移会有4种:

    这里由于i-2的出现,所以我们将两个数组长度分别增加1,相应的,用i取price值也要注意

    1. 持股 -> 不持股: 说明将手上的股票卖出: unhold[i-1] + prices[i-1] 

    2. 持股 -> 持股 :   说明没有动作: hold[i] = hold[i-1]

    3. 不持股 -> 持股:  说明新购入股票:unhold[i] = unhold[i-2] - prices[i-1]

    4. 不持股 -> 不持股: 说明没有动作:unhold[i] = unhold[i-1]

    状态转移方程为:

    unhold[i] = max(unhold[i-2] + prices[i-1] , unhold[i-1])

    hold[i] = max(unhold[i-1] - prices[i-1] , hold[i-1])

    代码:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            if(prices.size() < 2)
                return 0;
            vector<int> hold(prices.size()+1, 0);
            vector<int> unhold(prices.size()+1, 0);
            hold[1] = -prices[0];
            for(int i = 2; i <= prices.size(); i++){
                hold[i] = max(hold[i-1], unhold[i-2] - prices[i-1]);
                unhold[i] = max(unhold[i-1], hold[i-1] + prices[i-1]);
            }
            return unhold[prices.size()];
        }
    };

    --------------------------我是下一题分割线-------------------------------------

    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.

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

    Example 1:

    Input: [3,3,5,0,0,3,1,4]
    Output: 6
    Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
                 Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.

    Example 2:

    Input: [1,2,3,4,5]
    Output: 4
    Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
                 Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
                 engaging multiple transactions at the same time. You must sell before buying again.
    

    Example 3:

    Input: [7,6,4,3,1]
    Output: 0
    Explanation: In this case, no transaction is done, i.e. max profit = 0.

    解题思路:

    这道题说实话我一开始有想用单调栈来解但是觉得自己把自己弄混乱了。

    于是看了Grandyang的总结

    我决定过一会再看:)

    代码:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            if(prices.size() < 2)
                return 0;
            int n = prices.size();
            int g[n][3] = {0};
            int l[n][3] = {0};
            for(int i = 1; i < prices.size(); i++){
                int diff = prices[i] - prices[i-1];
                for(int j = 1; j <=2 ; j++){
                    l[i][j] = max(g[i-1][j-1] + max(diff, 0), l[i-1][j] + diff);
                    g[i][j] = max(l[i][j], g[i-1][j]);
                }
            }
            return g[n-1][2];
        }
    };

    -----------------------我是下一道题分割线-------------------------------------

    等一下

  • 相关阅读:
    仿新浪首页、主题、详情页,纯html静态页面
    hdoj 4790 Just Random 【数学】
    Codeforces 97B Superset 平面分治
    HDU 1017 A Mathematical Curiosity【看懂题意+穷举法】
    Codeforces Round #221 (Div. 2) D
    一个bug在redmine中的诞生到终结
    hi3531 SDK已编译文件系统制作jffs2文件系统镜像并解决这个问题 .
    js前端3des加密 后台java解密
    进程经常使用小知识汇总
    泛型集合的使用
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9237263.html
Copyright © 2011-2022 走看看