当前位置:   article > 正文

算法(买卖股票的的最佳时机)_算法题 买卖股票的最佳时机

算法题 买卖股票的最佳时机

1.题目描述

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多只能持有一股 股票。你也可以先购买,然后在 同一天出售。返回你能获得的最大利润 。

示例1

输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 (股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。 总利润为 4 + 3 = 7 。

示例2

输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。总利润为 4 。

示例3

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。

提示:

  • 1 <= prices.length <= 3 * 104
  • 0 <= prices[i] <= 104

解法一(动态规划):

分析:当日利润最大分为两种情况:(1)手中没有股票(2)手中有股票

当为情况(1)的时候,则可能是当日没有买入股票,利润是前一天卖掉股票的利润,也可能是当日把前一天的股票卖掉了的利润

当为情况(2)的时候,则可能是当日没有买入股票,利润是前一天买入股票的利润,也可能是当日买了如票的利润

根据分析就可以设置两个变量:nohold和hold,每一次更新一次当日的nohold和hold的最大利润

推导公式:nohold=max(hold+prices[i],nohold)

                  hold=max(hold,nohold-prices[i])

  1. package LeetCode;
  2. class Solution {
  3. public int maxProfit(int[] prices) {
  4. if(prices==null||prices.length==0){
  5. return 0;
  6. }
  7. int hold=-prices[0];
  8. int nohold=0;
  9. for(int i=1;i<prices.length;i++){
  10. hold=max(hold,nohold-prices[i]);
  11. nohold=max(nohold,hold+prices[i]);
  12. }
  13. return nohold;
  14. }
  15. public int max(int a,int b){
  16. if(a>b){
  17. return a;
  18. }else if(a==b){
  19. return a;
  20. }else{
  21. return b;
  22. }
  23. }
  24. }
  25. public class 买卖股票最佳时机 {
  26. public static void main(String[] args) {
  27. int[]A={1,5,4,9,2,3};
  28. Solution solution=new Solution();
  29. System.out.println(solution.maxProfit(A));
  30. }
  31. }

解法二(贪心算法

分析:根据观察每日股票的市值图,图像有增有减,又图像可以得出,最大利润就是所股票市值上升的差值之和。

首先,定义一个索引index,先判断当股票下降的情况,股票下降的话index就一直增,当下降到谷底的时候记录prices[index]的值,再判断增长的情况,index一直增长直到找到波峰,此时定义一个变量total来记录增长段的每次的差值之和(即最大利润),最后还有一层外层循环来让指针index不断的遍历整个数组从而实现代码。

  1. package LeetCode;
  2. class Sol {
  3. public int MaxProfit(int[] prices){
  4. if (prices == null||prices.length<2) {
  5. return 0;
  6. }
  7. int index=0,total=0;
  8. while(index<prices.length){
  9. while(index<prices.length-1&&prices[index]>=prices[index+1]){
  10. index++;
  11. }
  12. int min=prices[index];
  13. while(index<prices.length-1&&prices[index]<=prices[index+1]){
  14. index++;
  15. }
  16. total+=prices[index++]-min;//这里的index只能用index++,不然index就无法走到数组的长度+1,从而就无法推出循环
  17. }
  18. return total;
  19. }
  20. }
  21. public class 买卖股票最佳时机2 {
  22. public static void main(String[] args) {
  23. int[]B={1,5,4,9,2,3};
  24. Sol sol=new Sol();
  25. System.out.println(sol.MaxProfit(B));
  26. }
  27. }

解法三(贪心算法的优化)

分析:在贪心算法的基础上,定义一个变量ans,ans不断的累加上0和第二天和第一天的股票市值差值的最大值(即当第二天高于第一天就加上差值,若第二天小于第一天就加上0),这样下来就只用一个变量就可以不断地类加上增长的每一段,从而计算出最大利润。

  1. package LeetCode;
  2. class FastSolution{
  3. public int max(int []price){
  4. //判断数字是否为零或者未1而不符合题目要求
  5. if(price==null||price.length<2){
  6. return 0;
  7. }
  8. int ans=0;
  9. for (int i = 1; i <price.length ; i++) {
  10. ans+=Math.max(0,price[i]-price[i-1]);
  11. }
  12. return ans;
  13. }
  14. }
  15. public class 买卖股票最佳时机3 {
  16. public static void main(String[] args) {
  17. FastSolution fastSolution=new FastSolution();
  18. int []M={1,5,4,9,2,3};
  19. System.out.println(fastSolution.max(M));
  20. }
  21. }

注意:在代码实现的时候一定要注意边界问题,否则可能在循环的时候一直跳不出循环。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/628947
推荐阅读
相关标签
  

闽ICP备14008679号