硬怼动态规划、贪心算法——LeetCode每日一题:买卖股票的最佳时机 II

方法一:暴力法

这题的思路想要理清还是有点麻烦的,如果你连暴力法都想不出来的话,那更别提其他更好的算法了。暴力法的思路为利用递归列出所有可能的情况,在未买入股票的时候有买入和不买入两种情况,在买入股票后有卖出与不卖出两种情况,这样的话就可以把所有情况都列出来,类似于一颗二叉树,如图:

代码实现:

 class Solution {
 int res = 0;

public int maxProfit(int[] prices) {
    if(prices.length < 2){
        return 0;
    }
    getMax(prices,prices.length,true,0,0);
    return res;
}

public void getMax(int[] prices,int len,boolean status,int index,int profit){
    if(index == len){
        res = Math.max(res,profit);
        return;
    }
     //这个递归表示不进行任何操作(买入或卖出)
    getMax(prices,len,status,index + 1,profit);

    //两种情况,status = false表示未买入股票,status = true表示已经买入了股票
    //未买入股票可以选择买入,那么当前利益profit减去当前股票价值
    //已买入股票可以选择卖出,那么当前利益profit加上当前股票价值
    if(status){
        getMax(prices,len,false,index + 1,profit - prices[index]);
    }else{
        getMax(prices,len,true,index + 1,profit + prices[index]);
    }
}
}

方法二:贪心算法(Greedy Algorithm)

  • 算法简介
    贪心算法,又名贪婪法,是寻找最优解问题的常用方法,这种方法模式一般将求解过程分成若干个步骤,但每个步骤都应用贪心原则,选取当前状态下最好/最优的选择(局部最有利的选择),并以此希望最后堆叠出的结果也是最好/最优的解。{看着这个名字,贪心,贪婪这两字的内在含义最为关键。这就好像一个贪婪的人,他事事都想要眼前看到最好的那个,看不到长远的东西,也不为最终的结果和将来着想,贪图眼前局部的利益最大化,有点走一步看一步的感觉。}

  • 算法步骤
    步骤1:从某个初始解出发;
    步骤2:采用迭代的过程,当可以向目标前进一步时,总是做出在当前看来最好的选择,得到一部分解,缩小问题规模;
    步骤3:将所有解综合起来。

  • 回到题目中来
    既然要在题目中使用贪心算法,那么就要把题目每一步需要执行的步骤变成贪心算法的模式,及每一步都选取最优部分解。

     res =  (prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])
         =  prices[3] - prices[0]
    

仔细观察上面的式子,按照贪心算法,在索引为 1、2、3 的这三天,我们做的操作应该是买进昨天的,卖出今天的,虽然这种操作题目并不允许,但是它等价于:“在索引为 0 的那一天买入,在索引为 3 的那一天卖出”
理解了上面的意思的话,接下来就简单了,只需要在今天买入,并且判断在明天卖出活得的利益是否大于0,大于0的话就执行卖出操作,小于或者等于0的话就不卖出。

时间复杂度:O(n),只遍历了一次数组
空间复杂度:O(1),,只用了常熟级别的空间

  • 代码实现:
class Solution {

public int maxProfit(int[] prices) {
    if(prices.length < 2){
        return 0;
    }
    int res = 0;
    int index = 1;
    int temp = 0;
    while(index != prices.length){
        temp = prices[index] - prices[index - 1];
        if(temp > 0){
            res = res + temp;
        }
        index++;      
    }
    return res;
}  

}

总结:贪心算法比较适合找出单个最优解,当题解可能有多个最优解时,贪心算法也只能找出一个最优解,所以在需要输出多个最优解时,一般不会使用贪心算法

方法三:动态规划(Dynamic Programming)

这篇文章讲得十分详细:https://www.zhihu.com/question/23995189

其核心思想为:将一个问题拆成几个子问题,分别求解这些子问题,即可推断出大问题的解。

可以用贪心算法解决的问题,一般情况下都可以用动态规划。因此,不妨从 “状态”、“状态转移方程” 的角度考虑一下,使用动态规划的思路解决这道问题。

  • 解题思路
    首先定义状态dp二维数组,dp[天数][状态数],状态数分为0和1,dp[当前天数][0] 表示这一天不买股票,dp[当前天数][1] 表示这一天买入股票。

  • 确定第一天状态
    如果什么都不做,dp[0][0] = 0;
    如果买入股票,当前收益是负数,即 dp[0][1] = -prices[i];

然后第二天也分为买入股票和不买入,当买入股票时,那么就和第一天买的股票相比较,看哪个花的钱更少(这也是和贪心算法很相似的地方了把);如果不买股票的话,那么就用第一天买入股票的那个状态再卖出后的利润和什么都不做的利润相比较。

  • 代码实现:
 class Solution {

public int maxProfit(int[] prices) {
    int len = prices.length;
    if(len < 2){
        return 0;
    }
    //0表示不买股票
    //1表示买入股票
    int[][] dp = new int[len][2];
    dp[0][0] = 0;
    dp[0][1] = -prices[0];

    for(int i = 1;i < len;i++){
        dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] + prices[i]); //不买入
        dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0] - prices[i]); //买入
    }
    //最后一天肯定只能卖出股票或者保留现金
    return dp[len-1][0];
}  

}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345