关阿姨带你横扫LeetCode系列之买卖股票的最佳时机|Java 刷题打卡

866 阅读3分钟

关阿姨正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接

首先跟大家阐明一点就是,每道算法题都有多种解法,我们只讲LeetCode上几种优秀的解题思路~,希望可以帮助到大家,那我们先来看下题目描述吧~

一、题目描述:

给定一个数组,它的第 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。

二、思路分析:

1.暴力求解

这个题理解起来很简单,低买高卖,就能获得最大利润,对吧,我们来看一下具体该怎么做 首先定义一个变量代表我们的最大利润 maxprofit。 然后通过第一次循环,获取股票第一天到倒数第二天的价格。 因为如果最后一天买入股票就无法在未来的日子卖出,收益就为0,所以第一次循环的长度是prices.length - 1; 在今日,我们在进行循环,来获取我们今日后的股票价格。 让两天的价格做减法,获取我们在这天出售股票的利润profit。 把profit和maxprofit进行比较,取最大值赋值给maxprofit; 描述起来可能比较费劲,上代码吧

代码实现

 public int maxProfit1(int prices[]) {
         //最大利润,初始化为0
         int maxprofit = 0;
         //获得第i天的股票价格
         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;
     }

复杂度分析

时间复杂度:O(n^2) 空间复杂度:O(1)。只使用了常数个变量

2.一次遍历

首先我们定义一个变量来代表股票的最小价格minprice, 然后再定义一个变量代表我们获取到的最大利润maxprofit。 通过循环,我们来获取每天的股票价格。 在当天的时候,比较我们的当日的价格和我们的最小价格的大小。 如果我们的当日价格小于我们已知的最小价格,我们就把当日的价格赋值给minprice 如果当日的价格,不小于我们的最小价格,我们就去判断当日卖出股票的利润(当日价格减去最小价格)是否大于我们已知的最大利润maxprofit。 如果大于,我们就把当日的利润赋值给maxprofit,否则我们就进入下次循环。待循环完毕后,我们就获取到了最大的利润

代码实现

public int maxProfit2(int prices[]) {
         //定义目前已知最小价格
         int minprice = Integer.MAX_VALUE;
         //定义目前获得的最大利润
         int maxprofit = 0;
         //获取每一天的股票价格
         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),只使用了常数个变量

刷题总结

如果大家还有其他解题思路,只要能实现要求,都是没问题的,条条大路通罗马,不要仅仅局限于我讲的这种解法哈~,优秀的思路和代码更具备学习意义,我们一起加油吧