淘先锋技术网

首页 1 2 3 4 5 6 7

121. 买卖股票的最佳时机

股票问题详解
1、状态:有两种状态:持有或者没有股票。每天的状态是其中之一。
2、当天是否持有股票的最大利润 = max ( 前一天是否持有股票的最大利润, 今天是否买卖股票所造成的利润)

var maxProfit = function(prices) {
    let n = prices.length;
    // 定义一个二维数组
    let dp = new Array(n).fill(new Array(2));
    
    // dp[i][j]表示第i天股票状态为j时的最大利润(现金数)
    // 初始化第1天时的利润,不买入股票就是0,买入股票就是负值
    dp[0][0] = 0;
    dp[0][1] = -prices[0];
    
    // 从第二天算起
    for(let i=1;i<n;i++){
        // 第i天手里没有股票:第i-1天本来就没有 / 第i-1天有,但是第i天卖出了-- 取其中的最大值就是第i天的状态
        dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]+prices[i])
        
        // 第i天手里有股票:第i-1天本来就有  / 第i-1天没有,但是第i天买了(就是负值)-- 取其中的最大值就是第i天的状态
        dp[i][1] = Math.max(dp[i-1][1],-prices[i])
    }
    // 因为最后还是要卖出的,所以最大的利润是没有股票的状态
    return dp[n-1][0];
};

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

var maxProfit = function(prices) {
    const n = prices.length
    // dp[i][j]表示第i天股票状态为j时的最大利润,j有两种状态
    const dp = new Array(n).fill().map(()=>new Array(2).fill())
    
    // 第一天的情况
    dp[0][0] = 0 // 第一天不持有
    dp[0][1] = -prices[0] // 第一天持有,就是买东西了,利润为负

    // 从第二天开始
    for(let i=1; i<n; i++){
        // 不持有
        dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]+prices[i])
        // 第i天持有:第i-1天有 / 第i-1天没有,第i天买入了。但是此时的利润不是负数,因为之前可能进行了买卖,有存款在。
        dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]-prices[i])
    }
    // 最后要卖出
    return dp[n-1][0]
};

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

var maxProfit = function(prices) {
    const n = prices.length
    // dp[i][j]表示第i天股票状态为j时的最大利润,j有4种状态。第一次持有,第一次不持有,第二次持有,第二次不持有
    const dp = new Array(n).fill().map(()=>new Array(4).fill(0))
    
    // 第1天持有
    dp[0][0] = -prices[0] 
    dp[0][2] = -prices[0] 

    // 从第二天开始
    for(let i=1; i<n; i++){
        // 第一次持有
        dp[i][0] = Math.max(dp[i-1][0],-prices[i])
        // 第一次不持有
        dp[i][1] = Math.max(dp[i-1][1],dp[i][0]+prices[i])
        // 第二次持有
        dp[i][2] = Math.max(dp[i-1][2],dp[i][1]-prices[i])
        // 第二次不持有
        dp[i][3] = Math.max(dp[i-1][3],dp[i][2]+prices[i])
     
    }
    // 最后要卖出
    return dp[n-1][3]
};