题意整理

  • 已知股票每一天的价格波动。
  • 最多持有一只股,也就是买入时必须卖出之前持有的股。
  • 可以无限次买入和卖出股票,求最大收益。

方法一(贪心)

1.解题思路

为了在股票交易中获得最大收益,我们肯定希望在极小值点买入,在邻近的极大值点卖出,由于是邻近的极大值点,所以在买入点和卖出点之间股票肯定是单调递增的(记为最佳交易区间)。故而只需将这个区间内所有的上涨差值累加,即可得到这个区间的最大收益。最后总的最大收益是每个最佳交易区间收益的总和。

2.代码实现

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算最大收益
     * @param prices int整型一维数组 股票每一天的价格
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // 特殊情况判断
        if(prices.length==0||prices==null) return 0;

        int res=0;
        //遍历数组
        for(int i=1;i<prices.length;i++){
            //只要股票价格相对前一天是上涨的,则将差值加到res
            if(prices[i]>prices[i-1]){
                res+=prices[i]-prices[i-1];
            }
        }
        return res;
    }
}

3.复杂度分析

  • 时间复杂度:需要遍历一次数组,所以时间复杂度为图片说明
  • 空间复杂度:不需要额外的空间,所以空间复杂度为图片说明

方法二(动态规划)

1.解题思路

在买卖股票的交易过程中,有两个状态。一个是未持有股票的状态(即持有现金的状态,记位cash),另一个是持有股票的状态(记位hold)。最后获得的最大收益一定是未持有股票状态的最大值。我们需要弄清楚每次交易过程中,两种状态之间的关系。

  • 当未持有股票时,未持有股票状态的最大值,要么是之前的未持有股票状态最大值,要么是将当前持有的股票卖出,即图片说明
  • 当持有股票时,持有股票状态的最大值,要么是之前的持有股票状态最大值,要么是买入当前股票,即图片说明

动图展示:
图片说明

2.代码实现

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算最大收益
     * @param prices int整型一维数组 股票每一天的价格
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // 特殊情况判断
        if(prices.length==0||prices==null) return 0;

        // 初始化两种状态
        int cash=0;
        int hold=-prices[0];
        for(int i=1;i<prices.length;i++){
            //状态转移
            cash=Math.max(cash,hold+prices[i]);
            hold=Math.max(hold,cash-prices[i]);
        }
        return cash;
    }
}

3.复杂度分析

  • 时间复杂度:只需要遍历一次数组,所以时间复杂度为图片说明
  • 空间复杂度:需要额外常数级别的内存空间,所以空间复杂度为图片说明