代碼隨想錄算法訓練營|第三十五天|122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II。刷题心得(c++)

目录

讀題

122.买卖股票的最佳时机II

自己看到题目的第一想法

55. 跳跃游戏

自己看到题目的第一想法

看完代码随想录之后的想法

45.跳跃游戏II

自己看到题目的第一想法

看完代码随想录之后的想法

122.买卖股票的最佳时机II 實作

思路

Code

55. 跳跃游戏 - 實作

思路

Code

45.跳跃游戏II - 實作

思路

Code

錯誤代碼

正確代碼

總結

自己实现过程中遇到哪些困难

今日收获,记录一下自己的学习时长

相關資料


讀題

122.买卖股票的最佳时机II

自己看到题目的第一想法

看到這個題目我就想到最大子序和以及擺動序列,最大子序和讓我了解到尋求最大子序和的做法,以及如果是小於零我則捨棄掉之前的結果,重新開始,然後擺動序列是讓我在有波動時,就是preMax > curMax時在初始化變數值。也因此我思考了下,稍微去模擬後就寫出來了,但不知道是不是貪心算法的緣故,解的很虛阿。

55. 跳跃游戏

自己看到题目的第一想法

element代表可以跳得最遠距離,但不代表說不能跳小於這個步數的,首先想到兩個部分分別是

if(nums[0] > nums.size()) return true;
if(nums[0] == 0) return false;

之後想到的是,每次都是由nums[0],所開始跳躍,是要使用遞迴來解決嗎?

實在想不了解解法,直接看

看完代码随想录之后的想法

實在很巧妙,局部最優是遍歷元素時,每次都取最大的覆蓋範圍,在局部最優堆疊到全局最優,這樣思考起來的確很簡單,我剛剛的想法就會比較像是要去思考跳幾步,從思考跳幾步變成思考最大覆蓋範圍。

45.跳跃游戏II

自己看到题目的第一想法

我看到的想法是局部最優是,從0開始,每次都找我的覆蓋範圍內最大的數值跳躍過去

看完代码随想录之后的想法

看完之後跟我的整體思路有些類似,但我實際代碼還需要進行調整,還需要多看幾次。

122.买卖股票的最佳时机II 實作

思路

  1. 建立preMax、curMax以及result;
  2. 建立for循環,i從1開始持續加加,j初始為零 → 可以想像j為買入時間,i為賣出時間
  3. 今天的max,假設今日賣出的價值大於昨日賣出,則更新昨日賣出的樹值
  4. 假設今日賣出的價格小於昨日賣出,則將preMax加到result當中,並且將curMax以及preMax初始為零,j = i; 可以想像說昨日賣出比較好,所以result 加上preMax,preMax = 0代表已經賣出,j = i 代表今日買入。
  5. 假設有一段每天都比昨天賣好一點直到最後,那就遍歷結束後,preMax如果大於0,則把preMax加給result,確保結果確實存入

局部最優: 最大和 + nums[i],最大和必須比之前好,如果沒有比之前好,則應該在最大和時賣出。

Code

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int preMax = 0;
        int curMax = 0;
        int result = 0;
        for(int j = 0, i = 1; i < prices.size(); i++) {
            curMax = prices[i] - prices[j];
            if(curMax > preMax) preMax = curMax;
            if(preMax > curMax) {
                result += preMax;
                preMax = 0;
                j = i;
            } 
        }
        if(preMax > 0) result += preMax;

        return result;
    }
};

55. 跳跃游戏 - 實作

思路

  1. 建立cover,初始為0
  2. 假設當前跳躍的步數+當下跳躍到的nums[i]中的值, 大於最大覆蓋範圍,那就更新cover
  3. 假設cover >= nums.size() - 1 代表一定可以跳到最後一個元素, return true;
  4. 如果遍歷完都沒有可以覆蓋到最後一個元素的,return false;

Code

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int cover = 0;
        for(int i = 0; i <= cover; i++) {
            cover = max(i+nums[i], cover);
            if(cover >= nums.size() - 1) return true;
        }
        return false;
    }
};

45.跳跃游戏II - 實作

思路

  1. 局部最優是,從0開始,每次都找我的覆蓋範圍內最大的數值跳躍過去

錯誤點,應該是要讓i 逐步走,除非走到當前可以走到的最遠距離在更新next。

Code

錯誤代碼

class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size() == 1) return 0;
        int cover = 0;
        int result = 0;
        for(int i = 0; i <= cover;) {
            if(i + nums[i] >= cover) {
                cover = cover+nums[i];
                result++;
            }
            if(cover > nums.size() - 1) return result;
            int max = 0;
            for(int j = i; j <= cover; j++) {
                if(nums[j] >= max) {
                    max = nums[j];
                    i = j;
                }
            }
            
        }
        return result;
    }
};

正確代碼

class Solution {
public:
    int jump(vector<int>& nums) {
        int curMax = 0;    
        int result = 0;     
        int nextMax = 0;   
        for (int i = 0; i < nums.size() - 1; i++) {
            nextMax = max(nums[i] + i, nextMax);
            if (i == curMax) {                
                curMax = nextMax;
                result++;
            }
        }
        return result;
    }
};

總結

自己实现过程中遇到哪些困难

看完之後,對於貪心算法的思路,真的很挑戰自己的常識性思維,有時需要用很不同的角度去看問題才能找到解法,如果沒有這樣做,很可能會整個亂掉。

今日收获,记录一下自己的学习时长

今天大概學習了兩小時左右,整體還是覺得貪心算法很活,自己還需要多訓練用不同的角度看問題才行。

相關資料

● 今日学习的文章链接和视频链接

122.买卖股票的最佳时机II

https://programmercarl.com/0122.买卖股票的最佳时机II.html

55. 跳跃游戏

https://programmercarl.com/0055.跳跃游戏.html

45.跳跃游戏II

https://programmercarl.com/0045.跳跃游戏II.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值