日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

leetcode 55. 跳跃游戏 思考分析

發布時間:2023/12/1 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode 55. 跳跃游戏 思考分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目

給定一個非負整數數組,你最初位于數組的第一個位置。

數組中的每個元素代表你在該位置可以跳躍的最大長度。

判斷你是否能夠到達最后一個位置。

示例1:

輸入: [2,3,1,1,4]
輸出: true
解釋: 我們可以先跳 1 步,從位置 0 到達 位置 1, 然后再從位置 1 跳 3 步到達最后一個位置。

示例2:

輸入: [3,2,1,0,4]
輸出: false
解釋: 無論怎樣,你總會到達索引為 3 的位置。但該位置的最大跳躍長度是 0 , 所以你永遠不可能到達最后一個位置。

思考

這個題目,需要注意每個元素代表你在該位置可以跳躍的最大長度,而不是長度。也就是說如果是3,那么你可以走0,1,2,3步。
其次,觀察題目,不能到達最后一格的原因是:某一格元素為0,且之前沒有足夠步數跨越這個0
來分析一下示例2:[3,2,1,0,4],連續的0個數為1
我們先遍歷,找到元素0,下標為3。此刻從它前面的一個元素開始往前遍歷:
下標為2的元素為1,步數為1,(步數 - (連續0的第一個下標 - 當前下標 - 1)) =(1 - (3-2 -1))=1 <= 連續的0個數,所以不行
下標為1的元素為2,步數為2,(步數 - (連續0的第一個下標 - 當前下標 - 1)) =(2 - (3-1 -1))=1 <= 連續的0個數,所以不行
下標為0的元素為3,步數為3,(步數 - (連續0的第一個下標 - 當前下標 - 1)) =(3 - (3-0 -1))=1 <= 連續的0個數,所以不行

所以我們可以歸納出一個明顯的特征:(步數 - (連續0的第一個下標 - 當前下標 - 1))> 連續的0個數
只有滿足這個特征才算是可以到達最后一個位置。
代碼實現的時候還需要考慮特殊情況以及細節:
1、長度為1,直接為true
2、遍歷從 i=1開始,i= nums.size()-1,結束
3、獲取連續0的個數:

int succesive_zero = 0; if(nums[i] == 0) {succesive_zero = 1;for(int j = i;j < nums.size()-2;j++){if(nums[j] == 0 && nums[j+1] == 0) succesive_zero++;else break;} }

4、如果找到了可以可以跨越連續0的步數,那么將i指針移動到跳躍的格子。并且,如果在連續0之前沒有找到足夠大的步數跳躍,則說明不能到達最后一個格子,但是找到了,還需要遍歷之后的情況,直到整個數組都被遍歷了,且沒有出現不能跳過的情況,我們才能返回true。

int flag = 0; for(int j = i-1;j >= 0;j--) {if((nums[j]-(i-j-1)) > succesive_zero){i=i+succesive_zero;flag=1;break;} } if(flag == 0) return false;

AC代碼

class Solution { public:bool canJump(vector<int>& nums) {if(nums.size() == 1) return true;if(nums[0] == 0) return false;for(int i=1;i < nums.size()-1;i++){//如果當前為0,記錄連續0的個數int succesive_zero = 0;if(nums[i] == 0){succesive_zero = 1;for(int j = i;j < nums.size()-2;j++){if(nums[j] == 0 && nums[j+1] == 0) succesive_zero++;else break;}//cout<< "succesive_zero"<<succesive_zero << endl;//判斷i之前有沒有步數,在走到i后還有剩余的步數跳過這個0,說明暫時可以,否則不行int flag = 0;for(int j = i-1;j >= 0;j--){if((nums[j]-(i-j-1)) > succesive_zero){i=i+succesive_zero;flag=1;break;}}if(flag == 0) return false;}}return true;} };

參考,貪心思路,思路更加直觀,代碼邏輯更加簡單

參考代碼隨想錄的思路:https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA
跳幾步無所謂,關鍵在于可跳的范圍:
每次取最大的跳躍步數,這個就是跳躍的覆蓋范圍。
問題轉化為跳躍覆蓋范圍究竟可不可以覆蓋到終點。
每次移動取最大跳躍步數(得到最大覆蓋范圍),每移動一個單位,就更新最大覆蓋范圍。

**局部最優解:**每次取最大跳躍步數
**整體最優解:**最后得到整體最大覆蓋范圍,看是否能到終點。

編程細節:
1、i只能在cover范圍內移動,每移動一個元素,cover得到該元素數值,補充覆蓋范圍,讓i繼續移動下去。
2、cover每次只取max(鈣元素數值補充后的范圍,cover本身范圍)
3、如果cover >= 終點下標,直接return true;
AC代碼:

class Solution { public:bool canJump(vector<int>& nums) {//初始化覆蓋范圍int cover = 0;if(nums.size() == 1) return true;//從0開始的覆蓋范圍迭代for(int i = 0; i <= cover;i++){cover = max(i+nums[i],cover);if(cover >= nums.size() - 1) return true; }return false;} };

有一說一,這個思路確實妙!也很符合貪心的邏輯。

總結

以上是生活随笔為你收集整理的leetcode 55. 跳跃游戏 思考分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。