买卖股票的最佳时机

买卖股票的最佳时机
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

提示:
1 <= prices.length <= 105
0 <= prices[i] <= 104

第一种:动态规划
根据分析可以得到动态转移方程
dp[i] = Math.Max(dp[i - 1], prices[i] - minPrice);

using System;
using System.Collections.Generic;

public class Solution
{
    public int MaxProfit(List<int> prices)
    {
        int n = prices.Count;
        if (n == 0) return 0; // 边界条件

        int minPrice = prices[0];
        List<int> dp = new List<int>(new int[n]); // 初始化 dp 数组

        for (int i = 1; i < n; i++)
        {
            minPrice = Math.Min(minPrice, prices[i]);
            dp[i] = Math.Max(dp[i - 1], prices[i] - minPrice);
        }

        return dp[n - 1];
    }
}

// 示例用法
public class Program
{
    public static void Main()
    {
        Solution solution = new Solution();
        List<int> prices = new List<int> { 7, 1, 5, 3, 6, 4 };
        int maxProfit = solution.MaxProfit(prices);
        Console.WriteLine("最大利润: " + maxProfit); // 输出最大利润
    }
}

复杂度分析:
时间复杂度:O(N)
空间复杂度:O(N)

通过复杂度分析,可知实际上我们不需要维护一个dp,只需要维护一个最大值即可,所以可进一步优化代码,从而得到下面这种方式

//通过两个参数,在遍历的过程中获取最大的利润和最小的价格,一次遍历,如果第i天卖出股票,则最大利润为(该天的股价-前面天数中最小的股价),然后与已知的最大利润比较,如果大于则更新当前最大利润的值,动态规划
static public int MaxProfit1(int[] prices)
{
    int maxPorfit = 0;
    int minPrice = int.MaxValue;
    for (int i = 0; i < prices.Length; i++)
    {
        //动态规划,当前状态由之前的状态推导出来
        maxPorfit = Math.Max(maxPorfit, prices[i] - minPrice);
        minPrice = Math.Min(minPrice, prices[i]);
    }
    return maxPorfit;
}

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

第二种:单调栈(思路来源
(不作为商用,主要用于个人学习笔记)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

        static public int MaxProfit2(int[] prices)
        {
            int MaxProfit = 0;
            List<int> list = new List<int>();
            for (int i = 0; i < prices.Length; i++)
            {
                list.Add(prices[i]);
            }
            list.Add(-1);
            List<int> stack = new List<int>();
            //prices.SetValue(-1, prices.Length - 1); // 哨兵,设置哨兵的作用是保证所有的数都可以进行计算,比如递增的数组中,最后的结果将得到0,这并不是我们想要得到的比如[1,2]
            for (int i = 0; i < list.Count; i++)
            {
                while (stack.Count>0 && stack[stack.Count - 1] > list[i])//当出现这种情况的时候就要进行弹出栈并且,计算最大值
                {
                    MaxProfit = Math.Max(MaxProfit, stack[stack.Count - 1] - stack[0]);
                    stack.RemoveAt(stack.Count - 1);//移除最后一个,直到插入的值大于栈的最后一个
                }
                stack.Add(list[i]);
            }
            return MaxProfit;
        }

这种解决方式,仅仅作为思路拓展,实际上还是动态规划,只是形式不一样,和动规没什么太大区别,且空间和时间复杂度大于动规

空间复杂度分析
列表 list: 我们创建了一个额外的列表 list,它的大小为 n + 1(原始价格数组加上一个哨兵值),因此空间复杂度为 O(n)。
栈 stack: 在最坏情况下,栈 stack 也可能存储所有的价格,因此栈的空间复杂度也是 O(n)。
整个方法的空间复杂度为 O(n)。
结论
时间复杂度: O(n)
空间复杂度: O(n)

在unity中
在Unity游戏开发中,MaxProfit1 方法可以用于多种场景,特别是在涉及市场交易、资源管理或经济系统的情况下。以下是一些具体的应用场景:

1. 虚拟市场交易

在游戏中,玩家可能会与NPC(非玩家角色)进行商品交易。例如,玩家可以购买和出售资源(如武器、装备、材料等)。MaxProfit1 方法可以帮助计算在特定时间段内,玩家在交易中能够获得的最大利润。

示例:

  • 玩家在不同的时间点购买和出售资源,prices 数组可以代表这些资源的价格变化。使用 MaxProfit1 方法可以帮助玩家决定最佳的交易时机。

2. 资源管理

在一些策略或模拟类游戏中,玩家需要管理资源并在合适的时机进行投资或出售。例如,农场游戏中,玩家可能需要在不同的季节出售作物,价格会随时间波动。

示例:

  • prices 数组可以表示作物在不同季节的市场价格,使用 MaxProfit1 方法可以帮助玩家找到最佳的种植和出售时机,从而最大化收益。

3. 经济系统

在一些角色扮演游戏(RPG)中,游戏可能会有一个动态的经济系统,玩家的行为会影响市场价格。MaxProfit1 方法可以用于分析市场趋势,帮助玩家做出投资决策。

示例:

  • 玩家在游戏中通过完成任务、打怪等方式获得金币,prices 数组可以表示不同时间点的市场价格变化,使用该方法可以帮助玩家决定何时购买或出售物品以获得最大利润。

4. 游戏内物品拍卖

如果游戏中有拍卖系统,玩家可以在拍卖中出价购买物品。MaxProfit1 可以用来分析拍卖过程中物品的价格波动,以帮助玩家决定何时出价。

示例:

  • prices 数组可以表示物品在拍卖中的价格变化,使用该方法可以帮助玩家找到出价的最佳时机,从而以更低的价格获得物品。

5. 玩家经济活动分析

开发者可以使用此方法分析玩家的经济活动,评估市场的健康状况。例如,了解玩家在某个时间段内的购买行为和市场反应,以便调整游戏的经济机制。

代码示例

在Unity中,可以将 MaxProfit1 方法放在一个管理交易或经济的类中,并在合适的时机调用它。例如:

public class MarketManager : MonoBehaviour
{
    public int[] prices; // 价格数组,可以在运行时动态更新

    void Start()
    {
        // 示例价格数据
        prices = new int[] { 7, 1, 5, 3, 6, 4 };
        int maxProfit = MaxProfit1(prices);
        Debug.Log("最大利润: " + maxProfit);
    }

    static public int MaxProfit1(int[] prices)
    {
        int maxProfit = 0;
        int minPrice = int.MaxValue;
        for (int i = 0; i < prices.Length; i++)
        {
            maxProfit = Math.Max(maxProfit, prices[i] - minPrice);
            minPrice = Math.Min(minPrice, prices[i]);
        }
        return maxProfit;
    }
}

总结

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

  • 45
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leetcode..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值