算法之股票最佳时机系列问题(一次搞定6道股票问题)

算法套路十七——买卖股票问题:状态机 DP 买卖股票问题是一种典型的状态机 DP问题,设"未持有股票"和"持有股票"两个状态,每个节点表示某一状态下的最大收益,相邻节点之间的边表示在当前状态下进行一次交易得到的收益。 阅读详情

简述

本文旨在总结leetcode中遇到的一系列股票问题,分别详细阐述解决方法和各问题之间的区别。

目录

以上题目均来自leetcode

题目

1. 买卖股票的最佳时机
题目描述

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。

注意:你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5

算法

这道题由于只能进行一笔交易,因此只要选择最低的买点和最高的卖点,就可以获得最大的收益。

(1) 暴力法

最容易想到的暴力穷举法,从前往后遍历price,对于当前的prices[i],和i之前的所有价格进行比较,记录最大的收益。

代码如下:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        ans = 0
        for i in range(1, n):
            for j in range(i):
                ans = max(ans, prices[i]-prices[j])
        return ans

该算法的时间复杂度是O(n^2),在leetcode上最后一个测试过不了超时了,于是我们想想更优的算法。

(2) 一次遍历

前面我们提到了,我们的买点必须是当前时刻之前的最低价格,于是我们可以在遍历prices的时候记录下之前的最低股价,如果当前价格低于最低股价,则更新最低股价;如果高于最低股价,则更新收益。

代码如下:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:
            return 0
        n = len(prices)
        min_price = prices[0]
        ans = 0
        for i in range(1, n):
            if prices[i] < min_price:
                min_price = prices[i]
            else:
                ans = max(ans, prices[i]-min_price)
        return ans

由于只有一次遍历,因此时间复杂度为O(n),空间复杂度为O(1)。

这道题还可以用单调栈来解答,针对单调栈,我会重新写一篇文章来详细探讨。

2. 买卖股票的最佳时机 II
题目描述

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [7,1,5,3,6,4]
输出: 7

算法

这道题和前一道题不同之处在于可以进行多次交易。

(1) 动态规划
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        """
        dp[i][j]
        j: 0 没有持有  1 持有
        """
        n = len(prices)
        dp = [[0] * 2 for _ in range(n)]
        dp[0][1] = -prices[0]

        for i in range(1, n):
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
        
        return dp[-1][0]

时间空间复杂度都为O(n)。

(2) 峰谷法

对于数组[7, 1, 5, 3, 6, 4],绘制在图上如下:

我们想要最大化利润,其实就是在每一个波谷买入,每一个波峰卖出。这就是股市中所谓的“高抛低吸”,如果我们试图跳过一个波峰来获取更大的收益,那么会错过一笔交易,从而导致总利润减少。

代码如下:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        ans = 0
        i = 0
        while i < len(prices) - 1:  # 由于我们比较的是i和i+1,所以只需要遍历到n-2
            # 寻找波谷
            while i < len(prices) - 1 and prices[i] >= prices[i+1]:
                i += 1
            valley = prices[i]
            # 寻找波峰
            while i < len(prices) - 1 and prices[i] <= prices[i+1]:
                i += 1
            peak = prices[i]
            ans += peak - valley
        return ans

由于只进行一次遍历,因此时间复杂度为O(n)

(3) 简化

在上述解法中,我们考虑波谷买入,到了波峰才卖出。

我们换一种思路,我们虽然在波峰才卖出,但是在股价爬坡时期的每一天,我们都计算一下当前获得了多少收益,将每天获得的收益加起来,就是波峰卖出时这一阶段获得的收益。

如下图所示数组[1, 7, 2, 3, 6, 7, 6, 7],我们在第3天以2元买入,第4天股价3,收益1,总收益1;第5天股价6,收益3,总收益4;第6天股价7,收益1,总收益5。这种每天计算收益的方式和一次性波峰波谷计算的方式7-2=5相等。

代码如下:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        ans = 0
        for i in range(len(prices)-1):
            diff = prices[i+1] - prices[i]
            if diff > 0:
                ans += diff
        return ans

时间复杂度O(n),空间复杂度O(1)

3. 买卖股票的最佳时机 III
题目描述

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [3,3,5,0,0,3,1,4]
输出: 6

算法

这道题和第一题的不同之处在于最多可以进行两次交易。

刚接触到这道题,要求最多两笔交易,似乎无从下手。我们把问题分解一下,能不能分解成两次交易,并让两次的利润和最大呢?答案是可以的,我们可以在第一题的基础上,再进行一次交易,从而实现最大利润和。这样做的关键是如何确保两次交易不会重合呢?

用一个数组first_trade存储一次交易获得的最大利润,first_trade[i]表示i时刻能获得的最大收益,first_trade[-1](数组最后一个元素)就是第一题的答案。

得到first_trade数组之后,我们再从prices的末尾向前遍历一遍,记录遍历过程中的最大股价max_price,用max_price减去当前i时刻的股价prices[i],再加上前一时刻的最大利润first_trade[i-1],即:max_price-prices[i]+first_trade[i-1],就可以得到当前时刻的两次交易的最大收益。

代码如下:

  • python
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:
            return 0
        n = len(prices)
        first_trade = [0] * n
        min_price = prices[0]
        # 计算一次交易的最大利润,存入first_trade数组
        for i in range(1, n):
            first_trade[i] = max(first_trade[i-1], prices[i] - min_price)
            min_price = min(min_price, prices[i])

        max_price = prices[-1]
        res = first_trade[-1]
        # 计算两次交易的最大利润和
        for i in range(n-1, 0, -1):
            if prices[i] < max_price:
                res = max(res, max_price - prices[i] + first_trade[i-1])
            else:
                max_price = prices[i]
        return res
  • java
public class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        int[] record = new int[n];

        int profit = 0, min = prices[0];
        for (int i = 1; i < n; i++) {
            if (prices[i] < min) {
                min = prices[i];
            }
            profit = Math.max(profit, prices[i] - min);
            record[i] = profit;
        }

        int max = prices[n - 1], res = record[n - 1];
        for (int i = n - 2; i > 0; i--) {
            if (prices[i] > max) {
                max = prices[i];
            }
            res = Math.max(res, record[i-1] + max - prices[i]);
        }
        return res;
    }
}

由于遍历两次,时间复杂度为O(2n)≈O(n),存储数据用到了fist_trade数组,长度为n,因此空间复杂度为O(n)。

4. 买卖股票的最佳时机 IV
题目描述

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。

注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [2,4,1], k = 2
输出: 2

算法

这道题目是上一道题目更加泛化的版本,从k=2到k为任意数。

动态规划

对于交易的每一天,涉及到多种状态,包括:第几天、交易几笔、持有的股票数(0或者1),可以用三维动态规划来完成。

我们用一个三维n*k*2的矩阵dp来存储数据,第一维n表示第几天,第二维k表示进行了k笔交易,第二维0或者1表示手里持有的股票数。

对于任意一个数dp[i][j][0],表示第i天进行了j笔交易,手中没有股票时的利润,我们可以得到:
d p [ i ] [ j ] [ 0 ] = m a x ( d p [ i − 1 ] [ j ] [ 0 ] , d p [ i − 1 ] [ j ] [ 1 ] + p r i c e s [ i ] ) dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j][1] + prices[i]) dp[i][j][0]=max(dp[i−1][j][0],dp[i−1][j][1]+prices[i])
d p [ i ] [ j ] [ 1 ] = m a x ( d p [ i − 1 ] [ j ] [ 1 ] , d p [ i − 1 ] [ j − 1 ] [ 0 ] − p r i c e s [ i ] ) dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j-1][0] - prices[i]) dp[i][j][1]=max(dp[i−1][j][1],dp[i−1][j−1][0]−prices[i])
以上便是状态转移方程。

为了求解动态规划,我们还需要初始状态:
d p [ 0 ] [ j ] [ 0 ] = 0 dp[0][j][0] = 0 dp[0][j][0]=0
d p [ 0 ] [ j ] [ 1 ] = − p r i c e s [ 0 ] dp[0][j][1] = -prices[0] dp[0][j][1]=−prices[0]
上式表示在第1天的时候,如果手里没有持有股票,则利润为0;如果持有1只股票,则利润为-prices[0]。不要担心利润为负数,因为在卖出股票后会加上price,则就获得了正的利润。

疑问

为什么针对所有的j都需要设置为 d p [ 0 ] [ j ] [ 1 ] = − p r i c e s [ 0 ] dp[0][j][1] = -prices[0] dp[0][j][1]=−prices[0],而不是 d p [ 0 ] [ 1 ] [ 1 ] = − p r i c e s [ 0 ] dp[0][1][1] = -prices[0] dp[0][1][1]=−prices[0]?
因为给定的case,不一定能够完成k次交易,然而最后返回的结果是 d p [ n − 1 ] [ k ] [ 0 ] dp[n-1][k][0] dp[n−1][k][0]。假如只能完成一次交易,那最终的结果是从 d p [ i ] [ k − 1 ] [ 0 ] dp[i][k-1][0] dp[i][k−1][0]开始进行转移的。

另外还有一个注意的地方,我们知道对于长度为length的prices,最多可以进行length//2次交易,leetcode上的测试用例里会出现k非常大的情况,如果不对非常大的k进行处理,那么初始化dp矩阵时会消耗非常大的内存和时间,因此会不通过。

当k>=length//2时,相当于没有了k的限制,就回归到问题二,因此在这种条件下我们可以复用问题二的代码。

代码如下

  • python
class Solution:
    def maxProfit(self, k: int, prices: List[int]) -> int:
        n = len(prices)
        if n < 2:
            return 0
        if k > n / 2:
            return self.maxProfit_with_no_k_limit(prices)

        dp = [[[0] * 2 for _ in range(k+1)] for _ in range(n)]
        for i in range(n):
            for j in range(1, k+1):
                if i == 0:  # 初始状态
                    dp[i][j][0] = 0
                    dp[i][j][1] = -prices[0]
                else:  # 状态转移
                    dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j][1] + prices[i])
                    dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j-1][0] - prices[i])
        
        return dp[n-1][k][0]

    # 问题二代码,只是换了一个方法名
    def maxProfit_with_no_k_limit(self, prices: List[int]) -> int:
        ans = 0
        for i in range(len(prices)-1):
            diff = prices[i+1] - prices[i]
            if diff > 0:
                ans += diff
        return ans
  • java
public class Solution {
    public int maxProfit(int k, int[] prices) {
        int n = prices.length;
        if (n <= 1) {
            return 0;
        }
        if (k > n / 2) {
            return getProfitNoKLimit(prices);
        }

        int[][][] dp = new int[n][k + 1][2];

        // 设置初始状态
        for (int j = 1; j <= k; j++) {
            dp[0][j][1] = -prices[0];
        }

        for (int i = 1; i < n; i++) {
            for (int j = 1; j <= k; j++) {
                dp[i][j][0] = Math.max(dp[i-1][j][0], dp[i-1][j][1] + prices[i]);
                dp[i][j][1] = Math.max(dp[i-1][j][1], dp[i-1][j-1][0] - prices[i]);
            }
        }
        return dp[n-1][k][0];
    }

    private int getProfitNoKLimit(int[] prices) {
        int profit = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i-1]) {
                profit += (prices[i] - prices[i-1]);
            }
        }
        return profit;
    }
}

时空复杂度分析
两层n和k的循环,因此时间复杂度是O(kn)
由于我们使用n*k*2三维矩阵存储数据,空间复杂度为O(2kn)≈O(kn)

5. 最佳买卖股票时机含冷冻期
题目描述

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。

示例:

输入: [1,2,3,0,2]
输出: 3

算法
动态规划

我们继续沿用动态规划的思想,相比上一道题,由于不限制交易次数,因此少了一维k。

定义dp[i][0]表示第i天没有持有股票,dp[i][1]表示第i天没有持有1只股票。

由于有1天的冷冻期,因此如果第i天买入股票,需要满足第i-1天和i-2天的股票数都是为0。
这样就满足i-1天是冷冻期了。

因此状态转移方程:
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i])

初始状态:
dp[0][1] = - prices[0]

代码如下:

  • python
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        dp = [[0] * 2 for _ in range(n+2)]
        for i in range(2, n+2):
            if i == 2:
                dp[i][1] = - prices[i-2]
            else:
                dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i-2])
                dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i-2])
        return dp[n+1][0]

说明:由于当前i状态需要用到i-2时的状态,因此我们把dp数组长度定义为n+2,从2开始遍历,这样方便处理边界情况,而取prices的值的时候第i时刻取prices[i-2].

  • java
public class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (n < 2) {
            return 0;
        }
        int[][] dp = new int[n][2];
        dp[0][1] = -prices[0];
        for (int i = 1; i < n; i++) {
            dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            if (i > 1) {
                dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
            } else {
                dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);  // 因为i=1,就不需要看i-2
            }
        }
        return dp[n-1][0];
    }
}

时空复杂度分析
一次遍历,因此时间复杂度为O(n)
所用数组长度为n+2,因此空间复杂度为O(n)

6. 买卖股票的最佳时机含手续费
题目描述

给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。

你可以无限次地完成交易,但是你每次交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。

返回获得利润的最大值。

示例 1:

输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8

算法
动态规划

继续沿用动态规划的思想,我们在每次状态的股票数由1向0转移的时候在利润中减去fee。

状态转移方程:
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee)
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])

初始状态:
dp[0][1] = -prices[0]

代码如下:

class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        n = len(prices)
        dp = [[0] * 2 for _ in range(n)]
        for i in range(n):
            if i == 0:
                dp[i][1] = -prices[0]
            else:
                dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee)
                dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
        return dp[n-1][0]

时间复杂度:O(n)
空间复杂度:O(n)

简化动态规划

分析上面的算法我们可以知道,当前状态只和上一个状态有关,因此不必维护一个数组。
我们维护两个变量cash和hold,分别表示不持有股票和持有股票的最大利润。

状态转移为:
cash = max(cash, hold + prices[i] - fee)
hold = max(hold, cash - prices[i])

代码如下:

  • python
class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        cash, hold = 0, -prices[0]
        for i in range(1, len(prices)):
            cash = max(cash, hold + prices[i] - fee)
            hold = max(hold, cash - prices[i])
        return cash

说明:由于最后肯定要把股票全部卖掉,所以返回cash

  • java
class Solution {
    public int maxProfit(int[] prices, int fee) {
        int n = prices.length;
        if (n < 2) {
            return 0;
        }
        int buy = -prices[0] - fee, sell = 0;
        for (int i = 1; i < n; i++) {
            int tmp = sell;
            sell = Math.max(sell, buy + prices[i]);
            buy = Math.max(buy, tmp - prices[i] - fee);
        }
        return sell;
    }
}

时间复杂度:O(n)
空间复杂度:O(1)

参考资料

  1. 力扣官方解答
  2. 一个通用方法团灭 6 道股票问题
买卖股票的最佳时机系列---状态DP 给定一个数组prices,其中prices[i]是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成笔交易。你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。输入:k = 2, prices = [2,4,1]输出:2解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2。给定一个数组prices,它的第i个元素prices[i]表示一支给定股票第i天的价格。你只能选择。 阅读详情

相关推荐

算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码.zip

算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码算法导论大作业:股票买卖最佳时期系列问题 南开大学 算法导论源码

【算法】买股票系列

leetcode上有【买股票】的题很有意思,基本上也采用动态规划去做,今天总结一下。 在309. 最佳买卖股票时机含冷冻期解答中汇总了题目汇总了所有的买股票问题:力扣 1、121 买股票的最佳时机 链接:力扣 给定一个数组 prices ,它的第i 个元素prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润..

StudyWinter的博客 2139

潜在图神经网络学习笔记(Latent Graph Neural Networks for Human Skeleton-based Action Recognition)

在本文中,我们从一个新的角度来解决这个问题,通过将非结构化的骨架数据映射到潜在空间,如图2所示,这里称为潜在特征空间或嵌入空间,其中一组项嵌入在一个流形中[ 1 ],并且在潜在空间中彼此更相似的项被放置在彼此更接近的位置。潜在空间中的位置可以被认为是由一组潜在变量定义的,这些潜在变量来源于对象的相似性。将骨架数据嵌入到流形中,消除了远近邻居之间的冗余依赖关系,以解决加权问题。得到具有多尺度聚合特征的稀疏图矩阵结构,以更好地理解骨骼关节的直接加权信息。

qq_45631885的博客 489

算法——股票买卖问题

含有冷冻期 给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票): 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。 class Solution { public int maxProfit(int[] prices) { int res = 0; int n = pric

Think Different. 1687

Python模拟发送SOME/IP消息(Scapy模块)

SOMEIP提供服务、订阅、响应、通知等Python代码示例

liluo0815481的博客 3068

SAP采购订单中项目类别B(限制)的控制逻辑

在笔者所在企业中,框架类采购订单中项目类别需要选择B(限制)。今天笔者从比较全面的角度分析了一下这个项目类别B到底可以决定些什么?控制到什么?先从后台SPRO中打开相应的配置菜单。 打开项目类别B之后,可以看到一些配置信息,这里有一点与其它配置不同的地方,即无法新增项目,也无法修改现有项目。这个疑惑今后再去解决吧。当前只研究项目类别B的控制逻辑。 下面就参考上图中的配置分段来分析和测试其控制逻辑, 1、如项目类别配置图,所需材料值为不允许;经测试,如下图在采购订单创建时,不能输入物料编号条目。

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 6032

【算法】状态机DP 买卖股票系列

一个直接的方法就是将 dp 数组再扩展一维:dp[i][j]表示在第 i 天第 j 次交易时买入/卖出的最大收益。由于冷冻期的限制,buy[i] 的状态需要从 sell[i - 2] 转移过来,除此之外没有任何区别了。由于循环中的 下标 开始位置变成了 2,因此前面的初始化过程要写到 buy[1] 和 sell[1]。这是 买卖股票的最佳时机 II 的一道变形题,唯一的区别在于,卖出股票之后的第二天不能购买股票。的 sell 转移而来,sell 从。相比,状态转移的第一维下标是相同的。

小威的博客 388

DSP(数字信号处理器)技术概要

数字信号处理器(digital signal processor,DSP)是一种用于数字信号处理的可编程微处理器,它的诞生与快速发展,使各种数字信号处理算送得以实时实现,为数字信号处理的研究和应用打开了新局面,提供了低成本的实际工作环境和应用平台,推动了新的理论和应用领域的发展。目前,DSP技术在通信、航空、航天。雷达、工业控制、医疗、网络及家用电器等各个领域都得到了广泛应用。 1.1 DSP系统和芯片的结构特点1.1.1 DSP系统的基本结构通过传感数将非电物理量转换为模拟电信号,预处理一般包括放大器和滤

m0_46582485的博客 2万+

《LeetCode》—— 买卖股票的最佳时机

动态规划题目的讲解

m0_56069910的博客 3550

用户画像标签维度_搭建电商平台用户画像标签体系

01 整体思路电商平台连接了卖家和买家两端,最终目的都是促进交易,从而追求更高的销售额。提高人货匹配度是促进交易的关键,而提高人货匹配度的关键就是“让买家找到想要的货物”。本文结合“人、货、场”理论模型,尝试建立电商平台的用户画像标签体系。02 三类标签用户在平台购物的整体流程可以概括为:进入平台、选择商品、下单付款。可以将该过程抽象为“人、货、场”。即用户通过什么途径进入什么商品的页面...

weixin_31668621的博客 1642

Adaboost入门教程——最通俗易懂的原理介绍(图文实例)

Adaboost入门教程——最通俗易懂的原理介绍(图文实例)

Max的杂物仓 11万+

一文搞定所有 — — 买卖股票的最佳时机问题

第

SoyMilk的博客 1446

激光雷达+相机标定避坑指南:手把手教你用KITTI数据完成坐标转换

本文详细介绍了激光雷达与相机标定的实战指南,利用KITTI数据集完成精准坐标转换。从数据准备、工具链搭建到标定矩阵加载与验证,再到坐标转换流水线的工程实现,提供了全面的避坑技巧和工程实践建议。特别强调了多传感器融合中的常见问题及解决方案,帮助开发者提升自动驾驶和机器人感知系统的环境感知精度。

book8的博客 834

动态规划之--买卖股票的最佳时机系列问题

这篇文章也是看了卡哥视频后的一个分享。注:上述题目不一定非要使用动态规划,但是本文章全部使用动态规划。本系列的题目初始资金都是0。再注:卡尔视频中定义的是一个二维的dp数组,但其实可以简化为变量表示不同状态,因为后一天只受前一天的状态影响,因此本文章的代码大部分是使用变量代替数组。

saga_coder的博客 776

LAMMPS in文件详解:从零开始手把手教你配置金属分子动力学模拟

本文详细解析了LAMMPS in文件的配置方法,手把手教你完成金属分子动力学模拟的全流程。从软件环境准备、势函数选择,到使用Materials Studio构建模型、编写in文件进行能量最小化与系统弛豫,再到实施单轴拉伸生产模拟并提取应力应变数据,最后通过Python和OVITO进行结果分析与可视化,提供了完整的实战指南和常见问题排查技巧。

weixin_28475533的博客 527

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

买卖股票的最佳时机

MaxProfit1方法的应用场景十分广泛,尤其是在涉及经济、交易和资源管理的游戏中。通过合理使用该方法,可以为玩家提供更好的经济决策支持,从而提升游戏的可玩性和深度。

m0_55673629的博客 2195

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

买卖股票的最佳时机问题 C++

【题目描述】有一个价格数组prices,表示第i天的股票价格为prices[i],整个过程只能买入股票和卖出股票一次。并且买入股票必须再卖出股票之前。 【思路】贪心我们可以遍历一次数组,遍历到prices[i],表示在第i天卖出股票,为了使利益最大,我们需要在前i-1天中选择股票价格最低的一天买入。可以使用一个变量leftMin来记录前i-1天中,股票最低的价格。那么此时的最大利益就是prices[i]-leftMin。 动态规划dp[n][2]:dp[i][0]表示第i天未持有股票的最大利益,dp[i

2401_82677021的博客 1177

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

LeetCode之买卖股票的最佳时机系列共6道题

本文主要记录如何解决LeetCode中的《买卖股票的最佳时机》,相关题目总共有6道,主要解法是动态规划,也可以通过这几道题熟悉动态规划算法。

重点记录机器人和自动驾驶相关领域的技术,尤其是计算机视觉,视觉SLAM等,不仅有前言文献或必备算法的学习,也会有实际应用的点滴经验 385

算法日记-05买卖股票的最佳时机系列问题进阶

给定一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成交易。**注意:**你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

ilove_sf的博客 1633

【算法系列】买卖股票的最佳时机【JS代码】

通过上面的代码示例,我们可以看到一次遍历法不仅简洁易懂,而且非常高效。这种算法思想可以应用到很多类似的问题中,如求数组中的最长递增子序列、求字符串的最长回文子串等。然而,这个问题还有一个变种,即允许进行多次买卖股票(但每次买卖都需要先买入后卖出)。对于这个问题,我们需要使用不同的算法来解决。如果你对这个变种问题感兴趣,欢迎在评论区留言讨论。💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身"农奴"把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟! 898

动态规划之买卖股票问题(篇二)(买卖股票的最佳时机)

本篇博客主要讲解和,是上篇博客中股票问题的进阶。

2301_77160836的博客 1242

面试经典算法150题系列-买卖股票最佳时机||

经典面试题-数组操作之买股票的最佳时机||,贪心算法

欢迎来到betterManchester的博客 1243

动态规划之买卖股票问题(篇一)(买卖股票的最佳时机)

本篇博客和接下来的几篇博客主要讲解一下中的,本篇博客主要讲解和。

2301_77160836的博客 1343

代码随想录算法训练营第四十三天| 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、 123.买卖股票的最佳时机III

状态:做出来了因为股票就买卖一次,那么贪心的想法很自然就是取最左最小值,取最右最大值,那么得到的差值就是最大利润。每天的状态要么是持有股票要么是不持有,那么手头的钱就可以分为:dp[i][0]表示第i天持有当前股票的最大利润、dp[i][0]表示第i天不持有当前股票的最大利润。那么这个状态如何变化的呢?既然持有的话,说明第i-1天是持有且没有卖,或者第i-1天不持有,但是买入第i天的股票了。所以dp[i][0] = max(dp[i-1][0],-price[i])

weixin_43903745的博客 954

LeetCode 121. 买卖股票的最佳时机:一次遍历搞定的贪心解法

本文详细解析了LeetCode 121题"买卖股票的最佳时机"的贪心算法解法。通过一次遍历数组,记录当前最低股价并计算最大利润,实现O(n)时间复杂度的最优解。文章从题目理解、解题思路、代码解析到边界测试进行了全面讲解,重点分析了贪心策略的核心思想:始终记住最低买入价并计算当前利润。该方法适用于单次交易场景,为后续更复杂的股票问题奠定了基础。建议读者通过实际编码练习来巩固这一经典算法思路。

2401_86788218的博客 840

Leetcode经典题6--买卖股票的最佳时机

买卖股票的最佳时机

2301_81453175的博客 1134
上一篇: 算法之N数之和
下一篇: 算法之动态规划总结(11种DP类型,70道全部搞懂)
Elmerr
博客等级 码龄12年 178粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值