LeeCode(欲張りアルゴリズム)45_Jumping Game II
問題:
負でない整数の配列が与えられた場合、最初は配列の最初の位置にいます。
配列の各要素は、その位置でジャンプできる最大の長さを表します。
目標は、最小数のジャンプを使用して配列の最後の位置に到達することです。
例:
入力:[2,3,1,1,4]
出力:2
説明:最後の位置へのジャンプの最小数は2です。
下付き文字0から下付き文字1の位置にジャンプし、1ステップスキップしてから、3ステップスキップして配列の最後の位置に到達します。
説明:
配列の最後の位置にいつでも到達できると仮定します。
出典:LeetCode
リンク:https ://leetcode-cn.com/problems/jump-game-ii
著作権はLeetCodeが所有しています。商用の再版については、公式の承認に連絡してください。非商用の再版については、出典を示してください。
問題解決のアイデア:
方法1:逆に開始位置を見つける
最後の位置から始めて、この位置にジャンプできる前の位置を見つけます。ステップ数を最小限に抑えるために、前の位置をできるだけ前方に移動するように貪欲にする必要があります。
Javaコード:
public class 跳跃游戏_II {
public int jump(int[] nums) {
int position = nums.length-1;
int steps = 0;
while(position>0){
for(int i=0;i<position;i++){
if(i+nums[i]>=position){
position=i;
steps++;
break;
}
}
}
return steps;
}
}
方法2:前方に到達可能な最大の位置を見つける
特定の実装では、現時点で到達できる最大の添え字位置を維持し、それを境界として記録します。配列を左から右にトラバースし、境界に到達すると、境界を更新してジャンプの数を1つ増やします。
配列をトラバースするとき、最後の要素にアクセスしません。これは、最後の要素にアクセスする前に、境界が最後の位置以上である必要があるためです。そうでない場合、最後の位置にジャンプできません。最後の要素にアクセスすると、境界が最後の位置になると、「不要な数のジャンプ」が追加されるため、最後の要素にアクセスする必要はありません。
public int jump(int[] nums) {
int length = nums.length;
int end = 0;
int maxPosition = 0;
int steps = 0;
for(int i=0;i<length-1;i++){
maxPosition = Math.max(maxPosition, i+nums[i]);
if(i==end){
end = maxPosition;
steps++;
}
}
return steps;
}