• ARTS第五周


    ARTS第五周

    ARTS是什么?

    Algorithm:每周至少做一个leetcode的算法题;
    Review:阅读并点评至少一篇英文技术文章;
    Tip/Techni:学习至少一个技术技巧;
    Share:分享一篇有观点和思考的技术文章。

    Algorithm

    题目:买卖股票的最佳时机 IV

    解题思路

    这是LeetCode上买卖股票系列的最后一题,也是难度最大的一题。这里我们用标准的动态规划算法来解这道题,既然是用动态规划的办法,那就要先定义出动态规划的状态和状态转移方程。

    状态:根据题意,我们需要定义个三维的状态,分别是:天数, 交易次数,是否拥有股票的状态保持不动,买入一股,卖出一股)

    状态转移方程:如果当前手里没有股票,方程为:今天的利润 = Max(昨天的利润, 昨天的利润 + 今天卖出股票的钱);如果当前手里有股票,方程为:今天的利润 = Max(昨天的记录,昨天的利润 - 今天买入股票的钱)

    代码

    实际的代码就是把上面的状态转移方程用代码表达出来,再加上一些边界问题或特殊场景的判断即可。此题值得一提的是,当k大于数组长度的时候,其实题目就变成了“买卖股票的最佳时机II”,只要一直把利润相加就行了。

     class Solution {
        public int maxProfit(int k, int[] prices) {
            if (prices.length <= 0 || k <= 0){
                return 0;
            }
             
            int maxProfit = 0;
            //k大于数组长度的时候,其实题目就变成了“买卖股票的最佳时机II”
            if (k > prices.length){
                for(int i=1;i<prices.length;i++){
                    if(prices[i] > prices[i-1]){
                        maxProfit += prices[i] - prices[i-1];
                    }
                }
                return maxProfit;
            }
            
            //三维分别表示:天数, 交易次数,拥有股票的状态(不动,买入一股,卖出一股)
            int[][][] mp = new int[prices.length][k+1][2];
            /**
             * 初始化数据
             */
            for (int i=0;i<=k;i++){
                //状态:第一天、交易次数i、无股票
                mp[0][i][0] = 0;
                //状态:第一天、交易次数i、有股票
                mp[0][i][1] = - prices[0];
            }
    
    
            //第二天开始
            //天数
            for (int i = 1; i < prices.length; i++) {
                //交易次数
                for (int j = 0; j<= k; j++){
                    if (j == 0){
                        //当前没有股票,买入算一次交易,卖出不算
                        mp[i][j][0] = Math.max(mp[i-1][j][0], 0);
                        //当前拥有股票
                        mp[i][j][1] = Math.max(mp[i-1][j][1], 0);
                    }else{
                        //当前没有股票,买入算一次交易,卖出不算,1:前一天没有股票,2:前一天有股票今天卖出
                        mp[i][j][0] = Math.max(mp[i-1][j][0], mp[i-1][j][1] + prices[i]);
                        //当前拥有股票,1:前一天有股票,2:前一天没有股票今天买入
                        mp[i][j][1] = Math.max(mp[i-1][j][1], mp[i-1][j-1][0] - prices[i]);
                    }
    
                    int[] all = new int[]{maxProfit, mp[i][j][0], mp[i][j][1]};
                    maxProfit = Arrays.stream(all).max().getAsInt();
                }
            }
            return maxProfit;
        }
    }
    

    Review

    本次review的文章比较有意思,文章名为A faster alternative to Java Reflection,顾名思义是Java反射的一种更快的替代方案。作者在文中使用invokedynamic技术实现了一个自制的JavaBeanUtil。并且和Apache BeanUtils、 Jodd BeanUtil进行了性能比较,从作者展示的结果来看自制BeanUtil性能是最好的,他在放了源码在github上,感兴趣的话可以自己下载下来测试一下。最后,作者也提醒读者,自制BeanUtil只用来做实验展示invokedynamic的可能性,不建议用在生产环境。

    Tip/Techni

    Java实现获取最大数方法,包括int、double、char三种类型,其关键是调用max方法,它是一个重载方法,有无参方法可以直接获取int、long和double类型数组的最大值,也有接受一个参数的方法可以指定“比较方法”,具体示例如下:

    int[] all = {1, 2, 3};
    int max = Arrays.stream(all).max().getAsInt();
    
    double[] doubles = {1.2, 2, 3.62};
    double maxDouble = Arrays.stream(doubles).max().getAsDouble();
    
    Character[] chars = {'c', 'z', 'j'};
    Character character = Arrays.stream(chars).max(Character::compareTo).get();
    

    Share

    这周分享两个学习方法:

    1. 打怪升级学习法
    2. 沉淀学习法

    打怪升级学习法
    在平时的学习过程中,给自己设立一个切实可行的目标,就像打怪升级一样。

    这个方法的原理很简单,就是获取一定的成就感,然后支持你继续学习下去。

    具体的做法很多,比如写博客(就像我这篇文章这样_)当我看到你在文章下面留言或点赞,我就会为了每次都能写一篇好的文章而得到你的留言或点赞而努力,再比如在学习交流群里和别人交流你刚学到的知识、在某个帖子下面评论回复等等。

    沉淀学习法
    原理也同样很简单:知识需要沉淀,不要想试图一下子掌握所有,学习的过程是反复迭代、不断沉淀的过程。

    如果在学习的过程中碰到了“拦路虎”,可以尽可能地去想办法找答案也可以先沉淀一下,过几天再重新学一遍,说不定就会豁然开朗,所谓书读百遍其义自见也就是这个道理。

    如果您觉得本文对你有用,不妨帮忙点个赞,或者在评论里留言交流,欢迎您持续关注我的博客^_^
  • 相关阅读:
    python中join函数
    python实现反转字符串
    map函数
    python中lambda函数
    python中reduce函数
    python实现斐波那契数列
    迭代器和生成器
    经典算法动态图
    数据中心团队对于液体冷却的应用还需要适应
    物联网正将数据中心推向边缘
  • 原文地址:https://www.cnblogs.com/muxuanchan/p/10128294.html
Copyright © 2020-2023  润新知