Go&Java算法之股票的最大利润

299 阅读1分钟

这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战

股票的最大利润

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

 

示例 1:

输入: [7,1,5,3,6,4] 输出: 5

解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

输入: [7,6,4,3,1]

输出: 0

解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。  

限制:

0 <= 数组长度 <= 10^5

题解

算法一:动态规划(Java)

设共有 n 天,第 a 天买,第 b 天卖,则需保证 a < b ;可推出交易方案数共有: (n - 1) + (n - 2) + ... + 2 + 1 = n(n - 1) / 2

考虑使用动态规划降低时间复杂度,以下按照流程解题。

动态规划解析:

状态定义: 设动态规划列表 dpdp ,dp[i]dp[i] 代表以 prices[i]prices[i] 为结尾的子数组的最大利润(以下简称为 前 ii 日的最大利润 )。

转移方程: 由于题目限定 “买卖该股票一次” ,因此前 i 日最大利润 dp[i] 等于前 i - 1 日最大利润 dp[i-1] 和第 i 日卖出的最大利润中的最大值。

前i日最大利润=max(前(i−1)日最大利润,第i日价格−前i日最低价格)

dp[i]=max(dp[i−1],prices[i]−min(prices[0:i]))

初始状态: dp[0] = 0= ,即首日利润为 0 ;

返回值: dp[n - 1] ,其中 n 为 dp 列表长度。

class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) {
            return 0;
        }

        int max = 0;
        int minPrices = prices[0];
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] < minPrices) {
                minPrices = prices[i];
            }
            max = Math.max(max, prices[i] - minPrices);
        }
        return max;
    }
}

时间复杂度:O(N)

空间复杂度:O(1)

算法一:动态规划(Go)

func maxProfit(prices []int) int {
	length:=len(prices)
	if length==0{return 0}
	dp:=make([][]int,length)
	for i:=0;i<length;i++{
		dp[i]=make([]int,2)
	}
	
	dp[0][0]=-prices[0]
	dp[0][1]=0
	for i:=1;i<length;i++{
		dp[i][0]=max(dp[i-1][0],-prices[i])
		dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i])
	}
	return dp[length-1][1]
}

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

算法二:暴力法(Java)

我们需要找出给定数组中两个数字之间的最大差值(即,最大利润)。此外,第二个数字(卖出价格)必须大于第一个数字(买入价格)。

形式上,对于每组 i 和 j(其中 j > ii)我们需要找出 max(prices[j]−prices[i])。

public class Solution {
    public int maxProfit(int prices[]) {
        int maxprofit = 0;
        for (int i = 0; i < prices.length - 1; i++) {
            for (int j = i + 1; j < prices.length; j++) {
                int profit = prices[j] - prices[i];
                if (profit > maxprofit) {
                    maxprofit = profit;
                }
            }
        }
        return maxprofit;
    }
}