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. 沉淀学习法

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

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

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

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

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

原文地址:https://www.cnblogs.com/muxuanchan/p/10128294.html

时间: 2024-07-30 17:30:00

ARTS第五周的相关文章

每周进度条(第十五周)

第十五周进度条   第十五周 所花时间 1h 代码量(行)  100 博客量(篇)  1 学到的知识 对图片的处理 在Android程序中加入图片

201405644 嵌入式程序设计第五周学习总结

嵌入式课程设计第五周学习总结 标准 I/O 编程 标准 I/O 提供流缓冲的目的是尽可能减少使用 read()和 write()等系统调用的数量.标准 I/O 提供了 3 种类型 的缓冲存储.全缓冲.行缓冲.不带缓冲. 打开文件 打开文件有三个标准函数,分别为:fopen().fdopen()和 freopen().其中 fopen()可以指定打开文件的路径和模式,fdopen()可以指定打开的文件描述符和模式,而 freopen() 除可指定打开的文件.模式外,还可指定特定的 I/O 流. f

第五周的学习进度情况

第五周,不在状态,关于软件工程的学习并没有以往那么用心了,是该好好反思.   第四周 所花时间(包括上课) 8 代码量(行) 200+ 博客量(篇) 3 了解到的知识 软件需求分析的重要性 练习对编程学习的重要 虽然上周不在状态,但是,感觉周末表现良好,心也慢慢的收回来了,身边这么多榜样,一定要坚持,做好该做的!

2014025689 《嵌入式系统程序设计》第五周学习总结

<嵌入式系统程序设计>第五周学习总结 一.6.5(标准I/O编程)主要涉及的函数及知识点 标准的I/O的三种缓冲存储:全缓冲.行缓冲.不带缓冲. 1. 全缓存:当填满标准I/O缓存后才进行实际的I/O操作 2. 行缓存:当输入或输出中遇到行结束符时,标准I/O库执行I/O操作 3. 不带缓存:标准I/O库不对字符进行缓冲 打开文件的三个标准函数:  fopen().fdopen()和 freopen(). -fopen()可以指定打开文件的路径和模式 函数原型:FILE * fopen(con

每周进度表(第十五周)

  第十五周 所花时间(包括上课) 5(小时) 代码量(行) 200 博客量(篇) 7 了解到的知识点 如何对界面进行美化 如何处理anroid里的图片

20145307《信息安全系统设计基础》第五周学习总结PT2

20145307<信息安全系统设计基础>第五周学习总结PT2: 教材学习内容总结 之前有第一部分学习总结: http://www.cnblogs.com/Jclemo/p/5962219.html 以下为第二部分 执行汇编命令:gcc –s xxx.c –o xxx.s反汇编命令:objdump –d xxx 64位处理器得到32代码的命令:gcc –m32 –s xxx.c Ltme: 1.三种操作数: 立即数:常数值.表示为$c标准表示的整数. 寄存器:表示某个寄存器的内容. 存储器:根据

20145326蔡馨熠《信息安全系统设计》第五周学习总结

教材学习内容总结 书上有的内容我就不重复赘述了,只需要将部分重要的知识点归纳总结一下. 1.使用GDB的堆栈跟踪功能(GDB中有很多针对调用堆栈的命令,都需要一个目标栈帧,例如打印局部变量值的命令) 在栈帧之间切换 frame args 将当前栈帧设置为args(编号或Address)指定的栈帧,并打印该栈帧的简要信息. up n 向上回退n个栈帧(更外层),n默认为1. down n 向下前进n个栈帧(更内层),n默认为1. 打印栈帧信息(不移动栈帧) frame 打印当前栈帧的简要信息. i

马哥linux作业第五周&#39;

1.显示当前系统上root.fedora或user1用户的默认shell: egrep "^(root|fedora|user1)\>" /etc/passwd |cut -d: -f1,7 root|fedora|user1表示三者符合其一的选择条件 ()使其归组 ^表示以后面归组的条件开头 \>表示以空字符截断此前的条件字符,即后跟其它字符的单词将不匹配 2.找出/etc/rc.d/init.d/functions文件中某单词后面跟一组小括号的行,形如:hello():

学习进度条(十五周)

本周主要是对于团队开发项目的修改完善.   第十五周 所花时间(包括上课) 上课2小时,课后10小时 代码量(行) 200+ 博客量 2 了解到的知识点 服务器连接GET方法