我在leetcode用动态规划炒股

事情是这样的,突然兴起的我在letcode刷题

以上三题。

1. 121. 买卖股票的最佳时机

1.1. 暴力遍历,两次遍历

1.1.1. 算法代码

C# 复制代码
public class Solution {
    public int MaxProfit(int[] prices) {
        int profitValue=0;

        for(int i=0;i<prices.Length;i++)
        {
            for(int j=i+1;j<prices.Length;j++)
            {
                if(prices[j]>prices[i])
                {
                    if(prices[j]-prices[i]>profitValue)
                    {
                        profitValue=prices[j]-prices[i];
                    }
                }
            }
        }
        return profitValue;
    }
}

上述代码的逻辑为两次遍历,后一个值比前一个值大,并使用哨兵变量profitValue记录最大差值。

1.1.2. 算法复杂度

  • 时间复杂度: O ( n 2 ) = n ∗ ( n − 1 ) 2 O(n^2)=\frac {n*(n-1)}{2} O(n2)=2n∗(n−1)
  • 空间复杂度: O ( 1 ) O(1) O(1),因为只有哨兵变量profitValue

1.1.3. 算法问题

前面我们讲到,这个时间复杂度是 O ( n 2 ) O(n^2) O(n2),是一个指数函数。

那么在数据非常大的时候,其根据时间复杂度可以知道,其复杂度非常的高,如leetcode的超时案例

复制代码
[886,729,539,474,5,653,588,198,313,111,38,808,848,364,819,747,520,568,583,253,605,442,779,903,217,284,927,33,859,75,418,612,174,316,167,40,945,740,174,279,985,133,38,919,528,844,101,291,673,561,

.......
中间有3万个数值
.......

561,644,484,868,53,936,186,35,219,84,455,971,922,862,434,553,948,857,491,622,162,934,66,486,569,690,596,506,452,635,690]

其时间复杂度是: 30000 ∗ 29999 / 2 = 449985000 30000*29999/2=449985000 30000∗29999/2=449985000,其计算数值大的可怕。

1.2. 一次遍历

1.2.1. 算法代码

复制代码
public class Solution {
    public int MaxProfit(int[] prices) {
        int minprice = int.MaxValue;
        int maxprofit = 0;
        for (int i = 0; i < prices.Length; i++) {
            if (prices[i] < minprice) {
                minprice = prices[i];
            } else if (prices[i] - minprice > maxprofit) {
                maxprofit = prices[i] - minprice;
            }
        }
        return maxprofit;
    }
}

其算法,基本思路是:在最低点购入,在最高点卖出,由于for循环是从0开始的,所以其每一次minprice是当前时点前最低点购入值,故此算法可靠

1.2.2. 算法复杂度

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

2.2 122. 买卖股票的最佳时机 II

第一题相较比较简单,而第二题中增加了一个限定:可以购买多次,只是手上最多只有一支股票

2.1. 贪心算法

2.1.1. 算法代码

C# 复制代码
public class Solution {
    public int MaxProfit(int[] prices) {
        int ans = 0;
        int n = prices.Length;
        for (int i = 1; i < n; ++i) {
            int diffPrice=prices[i] - prices[i - 1];
            if(diffPrice>0)
            {
                ans += diffPrice;
            }
        }
        return ans;
    }
}

2.1.2. 算法思路与步骤

只要后一天的价格比今天高,那么我今天就买,后一天就卖。

2.1.3. 算法复杂度

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

2.2. 动态规划算法

2.2.1. 算法代码

C# 复制代码
public class Solution {
    public int MaxProfit(int[] prices) {
        if (prices.Length < 2) {
            return 0;
        }
        int[] OwnStocks=new int[prices.Length];
        int[] NoStocks=new int[prices.Length];

        OwnStocks[0]=-prices[0];
        NoStocks[0]=0;

        for(int i=1;i<prices.Length;i++)
        {
            OwnStocks[i]=Math.Max(OwnStocks[i-1],NoStocks[i-1]-prices[i]);
            NoStocks[i]=Math.Max(NoStocks[i-1],OwnStocks[i-1]+prices[i]);
        }

        return NoStocks[prices.Length-1];
    }
}

2.2.2. 算法思路与步骤

  • 由于不可以同时存在多支股票,所以每天只有可能有两种状态有股票、没有股票
  • 第一天存在股票=0-第一天股票价值;第一天不存在股票=0(没有购买或者当天售出)
  • 后续每一天,当天有股票的最大利益=Math.Max(前一天有股票的值,前一天没有股票的值-当天股票值购买股票)
  • 后续每一天,当前没有股票的最大利益=Math.Max(前一天没有股票的值,前一天有股票的值+当天股票值卖出股票`)

图解如下:

2.2.3. 算法复杂度

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) = 2 n O(n)=2n O(n)=2n

2.3. 123. 买卖股票的最佳时机 III

2.3.1. 动态规划算法

这一题就和第二题的动态规划类似,只是第二题是两个状态,而第三题是四个状态。

  • 没有买入
  • 第一次买入,没有卖出
  • 第一次买出,没有卖入
  • 第二次买入,没有卖出
  • 第二次买出

由于没有买入全程是0所以不做考虑,列出了5种,但实际上只有4种状态。

2.3.2. 算法代码

C# 复制代码
public class Solution {
    public int MaxProfit(int[] prices) {
        
        if(prices.Length<2)
        {
            return 0;
        }

        int oneBuy=-prices[0];
        int oneSale=0;
        int twoBuy=-prices[0];
        int twoSale=0;

        for(int i=1;i<prices.Length;i++)
        {
            oneBuy=Math.Max(oneBuy,-prices[i]);
            oneSale=Math.Max(oneSale,oneBuy+prices[i]);
            twoBuy=Math.Max(twoBuy,oneSale-prices[i]);
            twoSale=Math.Max(twoSale,twoBuy+prices[i]);
        }

        return twoSale;
    }
}

2.3.3. 算法复杂度

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) = 4 O(1)=4 O(1)=4
相关推荐
海上小飞龙7 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
青少儿编程课堂8 小时前
后缀自动机解析:本质不同子串与最长重复片段统计
c++·python·算法·bfs·信息学竞赛
朝朝辞暮i8 小时前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
乐迪信息9 小时前
港口船舶逆行怎么管?AI防爆摄像机搭载智能检测算法
大数据·人工智能·深度学习·算法·计算机视觉
Sirens.10 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
和裕10 小时前
全纸结构重型纸箱能否满足 1 吨以上设备出口熏蒸豁免要求?通关合规性全解析
大数据·运维·网络·人工智能·算法
lvwangshu10 小时前
T2 最长上升子序列(lis)题解
动态规划·题解·技巧·性质题·思维好题
tangguofeng11 小时前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法
苏打豆12 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
蛋蛋的就会顺顺的13 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣