LeetCode---买股票的最佳时机

题目描述

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。。

示例1

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例2

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

思路及实现

My first method

截取

思路: 由于这两天在学习集合的知识,当看到这个题的时候,脑海中就涌现出用集合的嵌套来解决这个问题,定义一个Map集键用于存放利润,由于Map集合的键是不重复,无序,无索引的。所以这个方法只能展示一唯一的利润,重复的不会被存储,但也可以达到本题最大利润的要求,而对应的值则存放买入和卖出日期。

实现:
具体代码实现:

public class Demo1 {
    public static void main(String[] args) {
        int[] nums = {7,1,5,3,6,4};
        int temp = 0;
        Map<Integer, List<Integer>> day = new HashMap<>();

        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                List<Integer> profit1 = new ArrayList<>();
                int profit = nums[j] - nums[i];
                if (profit > temp) {
                    Collections.addAll(profit1, i, j);
                    day.put(profit, profit1);
                }
            }
        }
        Set<Integer> keys = day.keySet();
        int maxProfit = 0;
        for (Integer key : keys) {
            if(maxProfit < key){
                maxProfit = key;
            }
//            List<Integer> value = day.get(key);
//            System.out.println(key +  "=>" + value);
        }
        System.out.println(maxProfit);
    }
}
/*结果:5*/

My second method

两次遍历

思路: 定义一个变量记录最大值,通过两次遍历,得到最大值即可。但这种方法写的代码优雅程度往往太低,需要用到两个循环,但也是一种思路。

实现:
具体代码实现:

public class theBesTime1 {
    public static void main(String[] args) {
        int[] nums = {7,1,5,3,6,4};
        int maxProfit = 0;
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                int profit = nums[j] - nums[i];
                if(profit > maxProfit){
                    maxProfit = profit;
                }
            }
        }
        System.out.println(maxProfit);
    }
}
/*结果:5*/
}

My third method

一次遍历

思路:
定义一个最小值在循环中,每判断一次,如果小于遍历到的数字小于最小值则把该值赋给最小值;如果不小于,则用该值与最小值作差,如果差大于最大值,则把该值赋给最大值,如果不大于,则代表前面已经存在的最大值仍是最大不需要赋值。

实现:
具体代码实现:

public class theBestTime2 {
    public static void main(String[] args) {
        int[] nums = {7,1,5,3,6,4};
        int minPrice = nums[0];
        int maxProfit = 0;
        for (int i = 1; i < nums.length; i++) {
            if(nums[i] < minPrice){
                minPrice = nums[i];
            } else if (maxProfit < (nums[i] - minPrice)) {
                maxProfit = nums[i] - minPrice;
            }
        }
        System.out.println(maxProfit);
    }
}/*结果:5*/

收获

通过该算法的学习,我脑海中涌现的一个方法使用集合嵌套的思想,虽然可以实现,但却把问题复杂化。虽然复杂但也顺便复习一下Map集合的使用,即所谓熟能生巧。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值