• [LeetCode] 122. Best Time to Buy and Sell Stock II


    Say you have an array prices 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.

    Constraints:

    • 1 <= prices.length <= 3 * 10 ^ 4
    • 0 <= prices[i] <= 10 ^ 4

    买卖股票II。这个题跟版本一的要求几乎一致,只是版本一要求只能买卖一次;版本二是可以买卖任意次数,也是求最大利润。这题也是有两种做法,一是贪心,一是动态规划。

    首先是贪心。贪心的来源,是因为不限买卖次数,所以只要下一个点的股价比上一个点高,就做交易。

    时间O(n)

    空间O(1)

    JavaScript实现

     1 /**
     2  * @param {number[]} prices
     3  * @return {number}
     4  */
     5 var maxProfit = function (prices) {
     6     // corner case
     7     if (prices === null || prices.length < 2) return 0;
     8 
     9     // normal case
    10     let profit = 0;
    11     for (let i = 1; i < prices.length; i++) {
    12         if (prices[i] > prices[i - 1]) {
    13             profit += prices[i] - prices[i - 1];
    14         }
    15     }
    16     return profit;
    17 };

    Java实现

     1 class Solution {
     2     public int maxProfit(int[] prices) {
     3         // corner case
     4         if (prices == null || prices.length == 0) {
     5             return 0;
     6         }
     7         
     8         // normal case
     9         int profit = 0;
    10         for (int i = 1; i < prices.length; i++) {
    11             if (prices[i] > prices[i - 1]) {
    12                 profit += prices[i] - prices[i - 1];
    13             }
    14         }
    15         return profit;
    16     }
    17 }

    动态规划的思路跟版本一很接近。设一个二维数组dp[][]其中第一维的长度是数组的长度len,第二维的长度是2,只有可能是0或1。这里第一维代表的就是遍历到某个位置的DP值,第二维表示的是在当前位置是否持有股票。持有记为1,不持有记为0。注意这里的不持有不是一直不买,而是卖出之后的不持有。版本二的一个引用

    这里DP值的更新细节如下

    dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);

    这一行的意思是在某一个位置如果不持有股票,那么他的DP值有可能是因为上一个位置也是不持有股票,或者是当前位置卖了股票而得到的

    dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);

    这一行的意思是在某一个位置如果持有股票,那么他的DP值有可能是因为上一个位置也持有股票,或者是当前位置买了股票导致的。这个地方的定义跟版本一很接近,区别在于版本一只能买卖一次,所以买的那一次是不依赖dp[i - 1][0]的值的,因为不持有股票的时候收益就是0。但是这道题因为允许多次交易所以dp[i - 1][0]有可能携带了前面几次交易的收益,这个信息不能丢失。

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int maxProfit(int[] prices) {
     3         int len = prices.length;
     4         if (len < 2) {
     5             return 0;
     6         }
     7         // 0:持有现金
     8         // 1:持有股票
     9         // 状态转移:0 → 1 → 0 → 1 → 0 → 1 → 0
    10         int[][] dp = new int[len][2];
    11         dp[0][0] = 0;
    12         dp[0][1] = -prices[0];
    13         for (int i = 1; i < len; i++) {
    14             // 这两行调换顺序也是可以的
    15             dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
    16             dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
    17         }
    18         return dp[len - 1][0];
    19     }
    20 }

    LeetCode 题目总结

  • 相关阅读:
    MATLAB入门学习(一)
    4.21小练
    poj2312 Battle City 【暴力 或 优先队列+BFS 或 BFS】
    Mutual Training for Wannafly Union #2
    4.7-4.9补题+水题+高维前缀和
    CodeForces 91A Newspaper Headline
    codeforces 792C. Divide by Three
    3.26-3.31【cf补题+其他】
    poj3259 Wormholes【Bellman-Ford或 SPFA判断是否有负环 】
    二叉树基础练习
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12321358.html
Copyright © 2020-2023  润新知