买股票的最佳时机三种解决方法java实现

3 篇文章 0 订阅

昨天在力扣遇到的这个题目,我自己使用的超级蠢的是暴力法,然后优化,两个for循环变一个,后来看了别人的解题思路,有一个很有趣的地方。一个问题如果换个思考问题的角度,也许就能找到更高效的方法,我觉得对我以后解题会有帮助,记录之。我自己也是个初入坑,学过算法设计分析但是上课没怎么好好听。
题目如下
在这里插入图片描述

1.暴力解题法

昨天在力扣遇到的这个题目,我自己使用的是暴力法,就是拿第 i 天股票价格减去前 i - 1 天股票价格的最小值,然后把这个值存储在一个大小为n(总天数)的数组中,最后在取数组中的最大值。这样做下来时间复杂度大概为O(n²)。
代码如下:

	public int maxProfit(int[] prices) {
		
		int[] minArr = new int[prices.length];
		for(int i = prices.length - 1;i >= 1;i --) {
			int min = minNum(prices, i);
			minArr[i] = (prices[i] - min > 0) ?  prices[i] - min : 0;
		}
		
		int max = 0;
		
		for(int i = 0;i < minArr.length ;i ++ ) {
			
			if (minArr[i] > max) {
				max = minArr[i];
			}
		}
		System.out.println(Arrays.toString(minArr));
		return max;
    }
	
	public  int  minNum(int[] a ,int len) {
		int min = 10000;
		for(int i = 0;i < len;i ++ ) {
			if (a[i] < min) {
				min = a[i];
			}
		}
		return min;
		
	}
2.对暴力法的优化

prices(i)是第 i 天的股票价格,我们最后要求的是max(prices[j]−prices[i]),j 为抛出那天,i 为买入那天 ,i < j。
现在我们可以这样考虑:
假设我是第 i 天,抛出股票,那么我获得最大利润的情况一定是在 i - 1 天中,股票价格最低的时候买入。我们只要用一个变量记录一个历史最低价格 minprice。随着天数 i 的增长,不断更新最低价格 minprice,和最大利润maxprofit。这是用空间换时间的做法。时间复杂度大概为O(n),空间消耗较大,
代码如下:

public int maxProfit(int[] prices) {
		//历史最低价格
		int minprice = Integer.MAX_VALUE;
		//最大利润值
		int maxprofit = 0;
		
		for(int i = 0;i < prices.length;i ++) {
			
			if (prices[i] < minprice) {
				//找i天之前的最小值
				minprice = prices[i];
			}else if (prices[i] - minprice > maxprofit) {
				//找i天之前最大利润
				maxprofit = prices[i] - minprice;
			}
		}
		return maxprofit;
	}
3.使用滑动窗口解题

假设股票价格数组为 7 9 12 3 6 8 。那么股票最多盈利 12 - 7 = 5。我们可以发现只有连续递增才会有机会盈利。上述的6个数有2次递增。我们只需求出这两次 递增中最大值(末位置)和最小值(起始值的)的差做比较即可。
用滑动窗口解题,要思考什么时候窗口滑动,什么时候停止。
在此题中,当数字递增的时候滑动窗口右边(end)界向右滑动,左边界(beg)不动。
数字不在递增(在第i个数的时候),求出窗口的前后差值并记录。此时赋值beg = end = i,窗口重新开始…
差值不断比较最后比出的最大值就是最大利润。时间复杂度和空间消耗都跟题解2差不多。
代码如下:

public int maxProfit(int[] prices) {
		
		//滑动窗口开始与结尾
		int beg = 0;
		int end = 0;
		//最大利润与本次递增数列的最大利润
		int Maxpro = 0;
		int todpro = 0;
		
		for(end = 0;end < prices.length;end ++) {
			if (prices[end] < prices[beg]) {
				beg = end;
			}
			todpro = prices[end] - prices[beg];
			Maxpro = Maxpro > todpro ?Maxpro:todpro;
		}
		return Maxpro;
	}
最后总结

提交了3次,后面两次时间消耗对于第一次有了极大的提升。但是3次的空间消耗都很大,只击败了5%的人。不知道哪位大佬还有牛啤的方法,能够提升一下空间消耗。弄出来再来补充。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值