【教3妹學(xué)編程-算法題】1696. 跳躍游戲 VI

瑟瑟發(fā)抖

3妹:好冷啊, 凍得瑟瑟發(fā)抖啦
2哥 : 沒想到都立春了還這么冷啊~
3妹:暴雪、凍雨、大雨,這天氣還讓不讓人活啦!?。?br> 2哥 :哎,好多人都滯留的高鐵站了,沒法回家了
3妹:我還不知道今天怎么回家呢,慘。
2哥:3妹,要不別回去了吧,我們就地過年
3妹:切,這里更冷,每天抖啊抖,跳啊跳才能緩解寒冷,我們家那兒可是有暖氣的。
2哥:好吧,回家也也要記得每天刷題啊,剛好今天的題目是跳躍的, 讓我們先做一下吧~

吃瓜

題目:

給你一個下標(biāo)從 0 開始的整數(shù)數(shù)組 nums 和一個整數(shù) k 。

一開始你在下標(biāo) 0 處。每一步,你最多可以往前跳 k 步,但你不能跳出數(shù)組的邊界。也就是說,你可以從下標(biāo) i 跳到 [i + 1, min(n - 1, i + k)] 包含 兩個端點的任意位置。

你的目標(biāo)是到達(dá)數(shù)組最后一個位置(下標(biāo)為 n - 1 ),你的 得分 為經(jīng)過的所有數(shù)字之和。

請你返回你能得到的 最大得分 。

示例 1:

輸入:nums = [1,-1,-2,4,-7,3], k = 2
輸出:7
解釋:你可以選擇子序列 [1,-1,4,3] (上面加粗的數(shù)字),和為 7 。
示例 2:

輸入:nums = [10,-5,-2,4,0,3], k = 3
輸出:17
解釋:你可以選擇子序列 [10,4,3] (上面加粗?jǐn)?shù)字),和為 17 。
示例 3:

輸入:nums = [1,-5,-20,4,-1,3,-6,-3], k = 2
輸出:0

提示:

1 <= nums.length, k <= 10^5
-10^4 <= nums[i] <= 10^4

思路:

思考

動態(tài)規(guī)劃 + 雙端隊列,
每一個位置的最大值取決于前面 k 步的最大得分,再加上當(dāng)前位置的得分,由此我們想到可以使用動態(tài)規(guī)劃來解決這個問題。

用 dp[i]來表示到達(dá)位置 i 的最大得分。初始狀態(tài) dp[0]=nums[0],表示位置 0的得分是它本身的得分。狀態(tài)轉(zhuǎn)移方程是

dp[i]=max?{dp[j]}
其中 max?(0,i?k)≤j<i。

其中前 k 步的最大值,使用優(yōu)先隊列可以達(dá)到 O(n×log?n)的時間復(fù)雜度,使用雙端隊列可以達(dá)到 O(n)的時間復(fù)雜度。

java代碼:

class Solution {
    public int maxResult(int[] nums, int k) {
        int n = nums.length;
        int[] dp = new int[n];
        dp[0] = nums[0];
        Deque<Integer> queue = new ArrayDeque<>();
        queue.offerLast(0);
        for (int i = 1; i < n; i++) {
            while (queue.peekFirst() < i - k) {
                queue.pollFirst();
            }
            dp[i] = dp[queue.peekFirst()] + nums[i];
            while (!queue.isEmpty() && dp[queue.peekLast()] <= dp[i]) {
                queue.pollLast();
            }
            queue.offerLast(i);
        }
        return dp[n - 1];
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容