LeetCode 股票系列(一)

简介: LeetCode 股票系列(一)

今天我们来聊聊 Leetcode 的华尔街之狼(The Wolf of Wall Street)系列,也称股票系列, 在 Leetcode 上有 6 题之多。

本文会通过讲解其中的几道经典题目再次探究动态规划的魅力,希望能帮助大家对 DP 有更深入的理解。

这类题目在面试中非常常见,也有很多的变种,比如我就被问过不止要返回 profit,还要返回在哪天交易。

不过万变不离其宗,把握住买卖的原则,你就是赢家。

1. Best Time to Buy and Sell Stock

给你一组数组 prices=[7,1,5,3,6,4]。prices[i] 代表在第i天股票的价格。你可以进行买与卖的操作,但你得先买了才能卖。(也就是不能 short)你最多进行一次买与卖的操作,问你能够赚到的最大收益是多少?从本题的数据例子来看,我们如果在 i=1 天买和在 i=4天卖,我们能够赚到 p[4]-p[1]=5 的收益。这是我们能够做到的最大收益,其它的操作都不能赚的比5多。

问题分析 :

首先如果我们在第 i 天进行买的操作,那么卖的操作一定得发生在第 i 天之后,也就是 prices[i+1 : n]

  • 以 prices=[7,1,5,3,6,4] 作为例子,如果我们在 prices[0] 买,那么卖一定发生在 prices[1 : 5]。
  • 同理,如果我们在 prices[1] 买,卖一定发生在 prices[2 : 5]。
    我们可以把所有的 (买,卖)  pair 生成出来然后找到收益性最高的那对即可。

方法1 :暴力枚举

public int maxProfit(int[] prices) {
        int maxProfit = 0; //我们可以不进行操作,所以初始是 0 而不是 INT_MIN
        for(int i = 0; i < prices.length; i++){
            //在 i 天 进行购买
            for(int j = i + 1; j < prices.length; j++){
                //在 j 天进行出售
                int profit = prices[j] - prices[i];
                maxProfit = Math.max(maxProfit, profit);
            }
        }
        return maxProfit;
    }

代码总结:

  • 我们枚举所有的 (i, j) pair,i 代表买,j 代表卖,并且 i < j,但以上暴力代码的时间复杂度是 O(n^2),我们可不可以做的更好呢?

时空复杂度:

  • 时间复杂度:O(N^2)
  • 空间复杂度:O(1)

方法2:

  • 如果我们在第 i 天进行买的操作,那么卖的操作一定还是得发生在 prices[i+1 : n] 这个定理是不变的。
  • 换句话说,对于每个买的操作,prices[i],我们只需要找到 prices[i+1 : n] 里最大的数即可。
  • 我们可以用一个dp array 去记录,dp[i] 表示 max(prices[i : n])
  • 如果我们在 i 这天进行买的操作,获得的最大的收益就是 dp[i+1] - prices[i] (这里我们要注意outbound)
public int maxProfit(int[] prices) {
        int maxProfit = 0;
        int n = prices.length;
        int dp[] = new int[n]; 
        dp[n - 1] = prices[n - 1];
        for (int i = n - 2; i >= 0; i--) {
            dp[i] = Math.max(prices[i], dp[i + 1]);
        }
        for (int i = 0; i < n - 1; i++) {
            maxProfit = Math.max(maxProfit, dp[i + 1] - prices[i]);
        }
        return maxProfit;
    }

时空复杂度:

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

方法3:

我们其实可以把空间压缩到 O(1),比起使用一个dp array 去记录,我们可以直接一边走一边记录。

public int maxProfit(int[] prices) {
        int n = prices.length;
        int maxSell = prices[n - 1];
        int maxProfit = 0;
        for (int i = n - 2; i >= 0; i--) {
            maxProfit = Math.max(maxProfit, maxSell - prices[i]);
            maxSell = Math.max(maxSell, prices[i]);
        }
        return maxProfit;
    }

时空复杂度:

  • 时间复杂度:O(N)
  • 空间复杂度:O(1)


目录
相关文章
|
6月前
|
算法
《LeetCode》—— 买卖股票的最佳时机
《LeetCode》—— 买卖股票的最佳时机
|
3月前
|
算法 Python
【Leetcode刷题Python】309. 最佳买卖股票时机含冷冻期
解决LeetCode上309题“最佳买卖股票时机含冷冻期”的Python代码示例,利用动态规划方法计算在含有冷冻期约束下的最大利润。
43 1
|
6月前
|
算法 索引
leetcode代码记录(买卖股票的最佳时机
leetcode代码记录(买卖股票的最佳时机
37 1
|
3月前
|
算法 Python
【Leetcode刷题Python】121. 买卖股票的最佳时机
解决LeetCode上121题“买卖股票的最佳时机”的Python代码示例,采用一次遍历的方式寻找最佳买卖时机以获得最大利润。
62 1
|
3月前
|
算法
leetcode188 买卖股票的最佳时机IV
leetcode188 买卖股票的最佳时机IV
62 0
|
3月前
|
算法 Python
【Leetcode刷题Python】714. 买卖股票的最佳时机含手续费
提供了两种解决买卖股票最佳时机含手续费问题的Python实现方法:贪心算法和动态规划算法。
46 0
|
3月前
|
算法 Python
【Leetcode刷题Python】122.买卖股票的最佳时机 II
LeetCode "买卖股票的最佳时机 II" 问题的Python代码实现,采用贪心算法在股票价格上升的每一天买入并卖出,以获得最大利润。
21 0
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
5月前
|
算法
leetcode题解:121.买卖股票的最佳时机
leetcode题解:121.买卖股票的最佳时机
40 0
|
6月前
|
算法
leetcode代码记录(买卖股票的最佳时机 III
leetcode代码记录(买卖股票的最佳时机 III
35 5