LeetCode 1696 跳躍遊戲 VI
阿新 • • 發佈:2020-12-26
LeetCode 1696 跳躍遊戲 VI
給你一個下標從 0 0 0 開始的整數陣列 n u m s nums nums 和一個整數 k k k 。
一開始你在下標 0 0 0 處。每一步,你最多可以往前跳 k k k 步,但你不能跳出陣列的邊界。也就是說,你可以從下標 i i i 跳到 [ i + 1 , m i n ( n − 1 , i + k ) ] [i + 1, min(n - 1, i + k)] [i+1,min(n−1,i+k)] 包含 兩個端點的任意位置。
你的目標是到達陣列最後一個位置(下標為
n
−
1
n - 1
n−1 ),你的 得分 為經過的所有數字之和。
請你返回你能得到的 最大得分 。
示例 1:
輸入:nums = [1,-1,-2,4,-7,3], k = 2
輸出:7
解釋:你可以選擇子序列 [1,-1,4,3] (上面加粗的數字),和為 7 。
示例 2:
輸入:nums = [10,-5,-2,4,0,3], k = 3
輸出:17
解釋:你可以選擇子序列 [10,4,3] (上面加粗數字),和為 17 。
示例 3:
輸入:nums = [1,-5,-20,4,-1,3,-6,-3], k = 2
輸出:0
這題很容易想到 DP,但是 DP 的複雜度是
O
(
n
k
)
O(nk)
O(nk) 的,顯然會超時,所以我們要用一種資料結構快速找到
[
i
−
k
,
i
−
1
]
[i-k,i-1]
[i−k,i−1] 的最大值,顯然容易想到單調佇列,用一個單調佇列維護區間,隊首即為最大值,再結合 DP 即可,AC程式碼如下:
class Solution {
public:
int maxResult(vector<int>& nums, int k) {
deque<int>q;
vector<int>dp(nums.size(),0);
dp[0]=nums[0];
q. push_back(0);
for(int i=1;i<nums.size();i++){
while(i-q.front()>k) q.pop_front();
dp[i]=dp[q.front()]+nums[i];
while(q.size()&&dp[i]>dp[q.back()]) q.pop_back();
q.push_back(i);
}
return dp[nums.size()-1];
}
};