代码随想录算法训练营第 41 天 | LeetCode121. 买卖股票的最佳时机 LeetCode122. 买卖股票的最佳时机ii LeetCode123. 买卖股票的最佳时机iii

代码随想录算法训练营

Day41 代码随想录算法训练营第 41 天 | LeetCode121. 买卖股票的最佳时机 LeetCode122. 买卖股票的最佳时机ii LeetCode123. 买卖股票的最佳时机iii



前言

LeetCode121. 买卖股票的最佳时机

视频讲解

LeetCode122. 买卖股票的最佳时机ii

视频讲解

LeetCode123. 买卖股票的最佳时机ii

视频讲解


一、LeetCode121. 买卖股票的最佳时机

1.题目链接

LeetCode121. 买卖股票的最佳时机

2.思路

(1)dp数组含义
dp[i][j]:第i天在j状态下手中现金的最大值(可以是负数)
i:第i天
j:j=0表示持有股票 j=1表示未持有股票
(2)转移方程

  1. dp[i][0]=max(dp[i-1][0],-prices[i]);
    上一次没有持有股票,说明之前从没持有过股票,现金是0;
    上一次持有股票,说明第i天卖掉,增加prieces[i]元现金
    2) dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);
    上一次没有持有股票,说明第i天买入,减少prieces[i]元现金;
    上一次持有股票,说明第i天没有变动
    (3)初始化
    dp[0][0]=-prices[0];—第一天买入

    dp[0][1]=0;------现金没有变化

3.题解

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n=prices.size();
        int dp[n][2];
        dp[0][0]=-prices[0];
            //0--持有股票 1--未持有股票
        dp[0][1]=0;
        for(int i=1;i<n;i++)
        {
            dp[i][0]=max(dp[i-1][0],-prices[i]);//上一次没有持有股票,说明之前从没持有过股票
            dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);
        }
        return dp[n-1][1];
    }
};

二、LeetCode122. 买卖股票的最佳时机ii

1.题目链接

LeetCode122. 买卖股票的最佳时机ii

2.思路

(1)dp数组含义
dp[i][j]:第i天在j状态下手中现金的最大值(可以是负数)
i:第i天
j:j=0表示持有股票 j=1表示未持有股票
(2)转移方程

  1. dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i]);
    上一次没有持有股票,之前可能持有过股票,现金可能变化过;
    上一次持有股票,说明第i天卖掉,增加prieces[i]元现金
    2) dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]);
    上一次没有持有股票,说明第i天买入,减少prieces[i]元现金;
    上一次持有股票,说明第i天没有变动
    (3)初始化
    dp[0][0]=-prices[0];—第一天买入

dp[0][1]=0;------现金没有变化

3.题解

class Solution {
public:
     int maxProfit(vector<int>& prices) {
        int n=prices.size();
        int dp[n][2];
        dp[0][0]=-prices[0];

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

三、LeetCode123. 买卖股票的最佳时机iii

1.题目链接

LeetCode123. 买卖股票的最佳时机iii

2.思路

(1)dp数组含义
dp[i][j]:第i天在j状态下手中现金的最大值(可以是负数)
i:第i天
j:
j=0表示从未持有股票
j=1表示第一次持有股票
j=2表示第一次卖出股票
j=3表示第二次持有股票
j=4表示第二次卖出股票

(2)转移方程
1)dp[i][0]=dp[i-1][0];
从未持有过股票,现金不可能变化过
2 ) dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);
上一次没有持有股票,说明第i天买入,减少prieces[i]元现金;
上一次第一次持有股票,说明第i天没有变动
3)dp[i][2]=max(dp[i-1][1]+prices[i],dp[i-1][2]);
上一次第一次持有股票,说明第i天卖出,增加prieces[i]元现金;
上一次第一次卖出股票,说明第i天没有变动
4) dp[i][3]=max(dp[i-1][2]-prices[i],dp[i-1][3]);
上一次第一次卖出股票,说明第i天买入,减少prieces[i]元现金;
上一次第二次持有股票,说明第i天没有变动
5) dp[i][4]=max(dp[i-1][3]+prices[i],dp[i-1][4]);
上一次第二次持有股票,说明第i天卖出,增加prieces[i]元现金;
上一次第二次卖出股票,说明第i天没有变动
(3)初始化
dp[0][0]=0;------现金没有变化

dp[0][1]=-prices[0];—第一天买入;
dp[0][2]=0;------第一天先买后卖,现金没有变化
dp[0][3]=-prices[0];—第一天买入,卖出,买;
dp[0][4]=0;—第一天买入,卖,买,卖;
(4)返回:最终不持有股票肯定比最终持有股票的情况现金多

3.题解

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        
        int n=prices.size();
        int dp[n][5];
        /*
        0--从未持有股票
        1--第一次持有
        2--第一次卖出后
        3--第二次持有
        4--第二次卖出后
        */
        dp[0][0]=0;
        dp[0][1]=-prices[0];
        dp[0][2]=0;
        dp[0][3]=-prices[0];//第一天可以买卖两次
        dp[0][4]=0;
        for(int i=1;i<n;i++)
        {
            dp[i][0]=dp[i-1][0];
            dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);
            dp[i][2]=max(dp[i-1][1]+prices[i],dp[i-1][2]);
            dp[i][3]=max(dp[i-1][2]-prices[i],dp[i-1][3]);
            dp[i][4]=max(dp[i-1][3]+prices[i],dp[i-1][4]);
        }
        int t= max(dp[n-1][0],dp[n-1][2]);
        return max(t,dp[n-1][4]);
    }
};

第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值