[LeetCode] 121. Best Time to Buy and Sell Stock

本文详细解析了股票买卖时机算法的实现,通过动态规划的方法,寻找最大获利的买入和卖出时机。以LeetCode上的经典题目为例,介绍了如何利用dp数组记录每日最大利润,以及维护历史最低价格的过程。

原题链接: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/

Buy and Sell Stock专题相关题目

121. Best Time to Buy and Sell Stock
122. Best Time to Buy and Sell Stock II
123. Best Time to Buy and Sell Stock III
188. Best Time to Buy and Sell Stock IV
309. Best Time to Buy and Sell Stock with Cooldown
714. Best Time to Buy and Sell Stock with Transaction Fee

1. 题目介绍

Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.

Example 1:
Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

给出一个数组,数组里面的值是一支股票每天的价格,寻找最大的获利。
获利= 卖出价格b - 买入价格a,并且a一定要在b的前面(先买入,才能后卖出)。
如果获利为负数,那么返回0,否则返回最大获利。

2. 解题思路

动态规划
采用dp[]数组来记录第 i 天可能获得的最大利润。small记录当前最小的价格。
以[7,1,5,3,6,4]为例,
0: dp[0] = -7,是第一天可能获得的最大利润,small =7
在这里插入图片描述
1:dp[1] = -6,此时最大的获利为-6,最大获利 = 当前的价格减去史上最小价格,也就是1-7,并且只有新的最大获利高于旧的最大获利时才更新。第一天买入7,第二天卖出1,获利为-6,比之前的-7大,所以更新。small=1
在这里插入图片描述
2: 此时最大的获利为5-1 = 4,small还是1
在这里插入图片描述
3:当前的最大获利为3-1=2,小于原来的最大获利4,所以不更新。
在这里插入图片描述
4:最大获利变为5,但是small还是1
在这里插入图片描述
5:这一步small更新,最大获利不更新
在这里插入图片描述
6:最后一步,dp数组的最后一个元素5就是最大获利了,如果它小于零,说明无论怎么买卖股票,都不会获利,于是就返回0
在这里插入图片描述

注意
这个题的测试样例中应该是有一个空数组的,直接用prices[0]会报错,因此需要加入判断prices[]是否为空的步骤。

实现代码

public class Solution {
    public int maxProfit(int prices[]) {
        int length = prices.length;
        
        if(length == 0){
            return 0;
        }
        
        int[] dp = new int[length]; 
        int small = prices[0];
        dp[0] = 0-prices[0];
        
        for(int i =1;i<length;i++) {
        dp[i] =(dp[i-1]>(prices[i]-small)?dp[i-1]:(prices[i]-small));
        	
        	if(small > prices[i]) {
        		small = prices[i];
        	}
        }
        return (dp[length-1]>0 ? dp[length-1] : 0);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值