1. 程式人生 > 遊戲 >PC遊戲秀將於今年6月12日迴歸

PC遊戲秀將於今年6月12日迴歸

✅做題思路or感想

這題的思路源於力扣上的nwpuCfy,這位先生的思路可堪一絕

這一題程式碼隨想錄上用的是貪心,但是我貪心太糟糕了,故這裡選用動態規劃來解

這一題的dp的思路並不難,難的是怎麼把這道題看成dp的題來做

dp四部曲

  1. dp陣列的意義

    • dp[i]表示的是[0, i - 1]上最長的擺動序列
  2. 遞迴公式

    • 當前面兩個差值不是一正一負時,則dp[i] = dp[i - 1]
    • 當前面兩個差值是一正一負時,則dp[i] = dp[i - 1] + 1
    • 如何判斷前面兩個差值一正一負?用點數論:(temp[i - 1] - temp[i - 2]) * (temp[i] - temp[i - 1]) < 0
      即是前面兩個差值一正一負。nwpCfy的思路可太強大了,這一步堪稱神來之筆
  3. 初始化

    • i = 0 時,最長擺動序列就是其本身了,即dp[0] = 1
    • i = 1時,這個時候還沒有產生兩個差值,而是隻有一個差值,故這裡最長擺動序列就是這個陣列的長度,dp[1] = 2
    • 為什麼要初始化到1呢,因為根據遞迴公式中有i - 2而言,遍歷i時必須要從2開始才能使得i - 2不為負數
  4. 遍歷順序

    • 這裡從遞迴公式就可以看出是從小推大,故是從i = 2開始遍歷

除上之外,這道題還需要提前去重!因為重複的元素不會影響最大擺動序列長度,所以沒有影響。而去重可以保證後面前後差值乘積要麼大於零,要麼小於零,不需要討論等於零的情況!!!(太神了)

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        vector<int> temp;
        temp.push_back(nums[0]);
        //這裡是去重:把不重複的元素裝到另一個數組中
        for (int i = 1; i < nums.size(); i++) {
            if (nums[i] != nums[i - 1])temp.push_back(nums[i]);
        }
        vector<int> dp(temp.size() + 1, 0);
        //初始化
        dp[0] = 1;
        dp[1] = 2;
        //遍歷順序:從小往大
        for (int i = 2; i < temp.size(); i++) {
            //判斷前兩個差值是否是一正一負
            if ((temp[i - 1] - temp[i - 2]) * (temp[i] - temp[i - 1]) < 0) {
                dp[i] = dp[i - 1] + 1;
            } else dp[i] = dp[i - 1];
        }
        return dp[temp.size() - 1];
    }
};