赞
踩
给你一个整数数组 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])
- package LeetCode;
- class Solution {
- public int maxProfit(int[] prices) {
- if(prices==null||prices.length==0){
- return 0;
- }
- int hold=-prices[0];
- int nohold=0;
- for(int i=1;i<prices.length;i++){
- hold=max(hold,nohold-prices[i]);
- nohold=max(nohold,hold+prices[i]);
- }
- return nohold;
- }
- public int max(int a,int b){
- if(a>b){
- return a;
- }else if(a==b){
- return a;
- }else{
- return b;
- }
- }
- }
- public class 买卖股票最佳时机 {
- public static void main(String[] args) {
- int[]A={1,5,4,9,2,3};
- Solution solution=new Solution();
- System.out.println(solution.maxProfit(A));
- }
- }
分析:根据观察每日股票的市值图,图像有增有减,又图像可以得出,最大利润就是所股票市值上升的差值之和。
首先,定义一个索引index,先判断当股票下降的情况,股票下降的话index就一直增,当下降到谷底的时候记录prices[index]的值,再判断增长的情况,index一直增长直到找到波峰,此时定义一个变量total来记录增长段的每次的差值之和(即最大利润),最后还有一层外层循环来让指针index不断的遍历整个数组从而实现代码。
- package LeetCode;
- class Sol {
- public int MaxProfit(int[] prices){
- if (prices == null||prices.length<2) {
- return 0;
- }
- int index=0,total=0;
- while(index<prices.length){
- while(index<prices.length-1&&prices[index]>=prices[index+1]){
- index++;
- }
- int min=prices[index];
- while(index<prices.length-1&&prices[index]<=prices[index+1]){
- index++;
- }
- total+=prices[index++]-min;//这里的index只能用index++,不然index就无法走到数组的长度+1,从而就无法推出循环
- }
- return total;
- }
- }
- public class 买卖股票最佳时机2 {
-
- public static void main(String[] args) {
- int[]B={1,5,4,9,2,3};
- Sol sol=new Sol();
- System.out.println(sol.MaxProfit(B));
-
- }
- }
分析:在贪心算法的基础上,定义一个变量ans,ans不断的累加上0和第二天和第一天的股票市值差值的最大值(即当第二天高于第一天就加上差值,若第二天小于第一天就加上0),这样下来就只用一个变量就可以不断地类加上增长的每一段,从而计算出最大利润。
- package LeetCode;
- class FastSolution{
- public int max(int []price){
- //判断数字是否为零或者未1而不符合题目要求
- if(price==null||price.length<2){
- return 0;
- }
- int ans=0;
- for (int i = 1; i <price.length ; i++) {
- ans+=Math.max(0,price[i]-price[i-1]);
- }
- return ans;
- }
- }
- public class 买卖股票最佳时机3 {
- public static void main(String[] args) {
- FastSolution fastSolution=new FastSolution();
- int []M={1,5,4,9,2,3};
- System.out.println(fastSolution.max(M));
- }
-
- }
注意:在代码实现的时候一定要注意边界问题,否则可能在循环的时候一直跳不出循环。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。