121. 买卖股票的最佳时机

题目

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

给定一个数组,它的第i个元素,是一支给定股票第i天的价格。

如果只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。即,最多只允许完成一笔交易,设计一个算法来计算你所能获取的最大利润

注意:你不能在买入股票前,卖出股票。

示例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。

解题思路

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

形式上,对于每组\(i\)\(j\)(其中\(j > i\)),需要找出\(\max(prices[j] - prices[i])\)

代码实现思路:

遍历价格数组,找到一个历史最低价格minPrice可以假设股票是在那天买的。那么,如果在第\(i\)天卖出股票,得到的利润prices[i] - minprice大于先前得到的最大利润maxProfit,则更新最大利润。当考虑完所有天数之时,就得到了答案。

prices[i]存在三种情况:

  1. prices[i] < minPrice:那么就找到了一个潜在的最佳买进时间,更新minPrice
  2. prices[i] = minPrice:不买不卖;
  3. prices[i] > minPrice:此时卖出,可赚利润为prices[i] - minPrice,如果大于maxProfit,则更新最大利润。

代码实现

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 121. 买卖股票的最佳时机(只交易一次)
 */
public class No121_BuyAndSellStock {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] strings = reader.readLine().split(",");
        int[] prices = new int[strings.length];
        for (int i = 0; i < strings.length; i++) {
            prices[i] = Integer.parseInt(strings[i]);
        }
        System.out.println(getMaxProfit(prices));
    }

    public static int getMaxProfit(int[] prices) {
        int minPrice = Integer.MAX_VALUE;
        int maxProfit = 0;
        /**
         * prices[i]存在三种情况:
         * 1. prices[i] < minPrice:那么就找到了一个潜在的最佳买进时间
         * 2. prices[i] = minPrice:不买不卖
         * 3. prices[i] > minPrice:此时卖出,可赚利润为prices[i] - minPrice
         */
        for (int i = 0; i < prices.length; i++) {
            if (prices[i] < minPrice) {
                minPrice = prices[i];
            } else if (prices[i] - minPrice > maxProfit) {
                maxProfit = prices[i] - minPrice;
            }
        }
        return maxProfit;
    }
}

复杂度分析

时间复杂度:\(O(n)\),只需要遍历一次。

空间复杂度:\(O(1)\),只使用了常数个变量。

posted @ 2021-03-15 22:59  chenzufeng  阅读(81)  评论(0编辑  收藏  举报