题解 | #买卖股票的最好时机(三)#

买卖股票的最好时机(三)

http://www.nowcoder.com/practice/2fea2b0349df4f7689f6f5a882e4f129

package main

import (
	"fmt"
)

func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func main() {
	var n int
	_, err := fmt.Scan(&n)
	for err == nil {
		prices := make([]int, n)
		for i := 0; i < n; i++ {
			fmt.Scan(&prices[i])
		}

		// ldp 表示昨天的状态
		// dp 表示今天的状态
		// dp[i][j] 表示剩余i次购买机会,且持有j份股票时,当天所能活动的的最大收益
		// 空间复杂度为O(1)
		// ----------------------------------------------------------------
		// 初始化第0天状态,ldp[i][0]表示不购入股票,收益为0
		// (或重复购入然后马上卖出,由于这种无意义操作完全不影响收益,将所有无意义操作移
		// 动至第0天处理,后续不再考虑无意义操作)
		// ldp[0][1]、ldp[1][1]表示第0天最后购入股票未卖出,收益为负
		// ldp[2][1]表示第0天剩余2次购买机会(未消耗购买机会),但却持有股票,为不可能
		// 事件,收益设置为负无穷大
		ldp := [3][2]int{{0, -prices[0]}, {0, -prices[0]}, {0, -(1 << 31)}}
		var dp [3][2]int
		// 时间复杂度度为O(n)
		for i := 1; i < n; i++ {
			// 今天剩余0/1次购买机会,且持有股票,有2种可能:昨天就持有股票今天无操作,
			// 或昨天未持有股票今天消耗一次购买机会买入
			dp[0][1] = max(ldp[0][1], ldp[1][0]-prices[i])
			dp[1][1] = max(ldp[1][1], ldp[2][0]-prices[i])
			// 今天剩余2次购买机会,但却持有股票,为不可能事件,收益设置为负无穷大
			dp[2][1] = -(1 << 31)

			// 今天剩余i次购买机会,且未持有股票,有2种可能:昨天持有股票今天卖出,或昨
			// 天就未持有股票今天无操作
			dp[0][0] = max(ldp[0][0], ldp[0][1]+prices[i])
			dp[1][0] = max(ldp[1][0], ldp[1][1]+prices[i])
			dp[2][0] = max(ldp[2][0], ldp[2][1]+prices[i])

			// “今天”变为“昨天”
			ldp = dp
		}
		fmt.Println(dp[0][0])

		_, err = fmt.Scan(&n)
	}
}
全部评论

相关推荐

投递字节跳动等公司10个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务