NC+LC:买卖股票的最好时机

1、股票(一次交易)

题目描述
假设你有一个数组,其中第个元素是股票在第 天的价格。
你有一次买入和卖出的机会。(只有买入了股票以后才能卖出)。请你设计一个算法来计算可以获得的最大收益。
示例
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

解法一:暴力解法

思路

从第一个元素开始往后遍历,与它后面的元素进行比较,遇到比它大的元素就求其差值,通过比较求出最大的差值,这种做法的时间复杂度为

实现代码

import java.util.*;

public class Solution {
    public int maxProfit (int[] prices) {
        // write code here
        if(prices == null || prices.length == 0) {
            return 0;
        }
        int max = 0;
        for(int i = 0; i<prices.length-1; i++){
            for(int j = i+1; j<prices.length; j++){
                if(prices[j] > prices[i]){
                    int  tmp = prices[j] - prices[i];
                    if(max < tmp){
                        max = tmp;
                    }
                }
            }
        }
        return max;
    }
}

解法二:贪心算法

思路

  • 这题实际上是在求
  • 利用贪心算法的思路(不考虑全局,从头开始求局部最优解,保持在这个局部范围内的最小买入值)维护范围内最小
  • 保持当前的最小买入值,将往后的值进行相减求差值,再通过比较获得局部的最大收益值并将其保持,以此类推不断逼近得到最大的差值
  • 此解法时间复杂度为

实现代码

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length == 0) return 0;
        int buy = prices[0];
        int max = 0;
        for(int i = 1; i < prices.length; i++){
            buy = Math.min(buy, prices[i]); //记录当前的最小买入值
            max = Math.max(max, prices[i] - buy); //求当前局部的最大收益值
        }
        return max; //最终得到全局的最大收益值
    }
}

2、股票(两次交易)

题目描述
假定你知道某只股票每一天价格的变动。
你最多可以同时持有一只股票。但你最多只能进行两次交易(一次买进和一次卖出记为一次交易。买进和卖出均无手续费)。
请设计一个函数,计算你所能获得的最大收益。

解法一

思路

以当前位置作为第二次交易的买入点,保持当前价格与第一次收益的最小差值作为第二次买入的价格

实现代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 两次交易所能获得的最大收益
     * @param prices int整型一维数组 股票每一天的价格
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // write code here
        int fstBuy = Integer.MAX_VALUE;
        int fstSell = 0;
        int secBuy = Integer.MAX_VALUE;
        int secSell = 0;
        for(int price : prices){
            //第一次交易
            fstBuy = Math.min(fstBuy, price);
            fstSell = Math.max(fstSell, price-fstBuy);
            //以当前位置作为第二次交易的买入点,保持当前价格与第一次收益的最小差值作为第二次买入的价格
            secBuy = Math.min(secBuy, price-fstSell);
            secSell = Math.max(secSell, price-secBuy);
            
        }
        return secSell;
    }
}

解法二

思路

  • 可以先从后往前遍历,求出从当前点到之后的一次交易的最大收益值,将其记录在一个数组中
  • 再从前往后进行遍历,按照一次交易的贪心算法思路,求出第一次交易的收益值加上当前位置往后的第二次收益值,通过比较求出其中的最大值

实现代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 两次交易所能获得的最大收益
     * @param prices int整型一维数组 股票每一天的价格
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // write code here
        int n = prices.length;
        if(n<2) return 0;
        //从后往前遍历,f[i]记录了从i点到之后的一次交易的最大收益
        int[] f = new int[n];
        int max = prices[n-1];
        f[n-1] = 0;    //初始化
        for(int i = n-2; i>=0; i--){
            max = Math.max(max, prices[i]);//记录当前的最大卖出点
            f[i] = Math.max(f[i+1], max-prices[i]);
        }
        int res = 0;
        //从前往后遍历
        int min = Integer.MAX_VALUE;
        for(int i = 0; i<n-1; i++){
            min = Math.min(min, prices[i]);
            //每次在第一次交易的收益上加上当前位置之后对应的f[i+1],通过比较求最大值
            res = Math.max(res, prices[i] - min + f[i+1]);
        }
        return res;
    }
}

3、股票(多次交易)

题目描述
给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

解法一:贪心算法

思路

  • 因为可以进行多次交易,那么要想获得最大收益,就需要将每一个上升的区间的收益进行相加
  • 只需从头开始遍历,将前后两数之间的差值计算出来,大于0的就说明有收益,将收益值进行累加

实现代码

class Solution {
    public int maxProfit(int[] prices) {
        if(prices == null || prices.length == 0) return 0;
        int sumValue = 0;
        for(int i = 0; i < prices.length - 1; i++){
            //遍历数组,将后一个数减去前一个数,大于0就说明有收益,进行累加
            int dif = prices[i + 1] - prices[i];
            if(dif > 0){
                sumValue += dif;
            }
        }
        return sumValue;
    }
}

解法二:动态规划



全部评论

相关推荐

霁华Tel:秋招结束了,好累。我自编了一篇对话,语言别人看不懂,我觉得有某种力量在控制我的身体,我明明觉得有些东西就在眼前,但身边的人却说啥也没有,有神秘人通过电视,手机等在暗暗的给我发信号,我有时候会突然觉得身体的某一部分不属于我了。面对不同的人或场合,我表现出不一样的自己,以至于都不知道自己到底是什么样子的人。我觉得我已经做的很好,不需要其他人的建议和批评,我有些时候难以控制的兴奋,但是呼吸都让人开心。
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务