タイトル説明
タイトルリンク:https://leetcode-cn.com/problems/zui-xiao-tiao-yue-ci-shu/
問題解決のアイデア:
- bfsを直接使用して、ジャンププロセスをシミュレートし、適切に最適化します。
- bfsのプロセスでは、位置に到達するたびに、次のステップで到達できるすべての位置が、N以上の位置にジャンプするまでキューに追加されます。
- 最適化:(1)座標iの場合、iがスキップされた場合、再度ジャンプする必要はありません。再度ジャンプするには、ステップ数を増やす必要があるためです。したがって、iをキューに繰り返し追加する必要はありません。(2)新しい位置iに到達するたびに、[0、i-1]がスキップされたかどうかを判断する必要があります。この列挙は、多くの時間計算量を引き起こします。ある時点で位置jにジャンプすると、[0、j-1]のすべての位置に「ジャンプバック」するので、次回位置iにいるときは、[j、i]かどうかを確認するだけで済みます。 -1]はスキップされます。つまり、毎回「最大j」(低と表示)を記録するだけで済みます。「次の座標」を考えるたびに、低いところから判断するだけです。
- この質問は、正方形の上を迷路を歩く質問に類似している可能性があります。
ACコード
//Java代码
//Node表示某一"位置","位置"的属性有:跳跃的次数step、当前坐标position、以及下一步能往右跳所能到达的坐标。
//此处所说的坐标是数组下标
class Node{
int step; //跳跃次数
int position; //所在坐标
int next; //从当前坐标往后跳可以到达的坐标
//next可以用来判断下一个位置是否超过N,以简化代码
public Node(int s,int p,int n){
this.step=s;
this.position=p;
this.next=n;
}
}
class Solution {
public int minJump(int[] jump) {
int N=jump.length;
int vis[]=new int[N]; //vis[i]等于1表示坐标i已经被跳到过
Queue<Node>queue=new LinkedList<>(); //存储“位置”的队列
int s=0,p=0,n=jump[0],low=1;
queue.offer(new Node(s,p,n)); //起点加入队列
vis[0]=1;
while(!queue.isEmpty()){
Node now=queue.remove();
s=now.step;
p=now.position;
n=now.next;
if(n>=N) return s+1; //到达大于N的位置时直接返回步数
//将所有能到达且还没有“跳到过”的位置加入队列
else{
for(int j=low;j<p;j++)
if(vis[j]==0){
queue.offer(new Node(s+1,j,j+jump[j]));
vis[j]=1;
}
if(vis[n]==0){
queue.offer(new Node(s+1,n,n+jump[n]));
vis[n]=1;
}
}
low=Math.max(low,p); //更新
}
return s;
}
}
JAVAキューの概要:
初めてJavaキューを使用して、いくつかの一般的な方法を要約します。
add()
は、指定された要素をこのキューに挿入し(すぐに実行可能で、容量制限に違反していない場合)、成功するとtrueを返し、現在使用可能なスペースがない場合はIllegalStateExceptionをスローします。
element()
は、このキューの先頭を取得しますが、削除しません。
Offer()
は、指定された要素をこのキューに挿入します(すぐに実行可能で、容量制限に違反しない場合)。容量制限キューを使用する場合、このメソッドは通常、挿入できない可能性があるadd()よりも優れています。要素ですが、例外をスローします。
peek()
は、このキューの先頭を取得しますが、削除しません。このキューが空の場合、nullを返します。
poll()
は、このキューの先頭を取得および削除し、このキューが空の場合はnullを返します。
remove()
は、このキューの先頭を取得および削除します。
キュー宣言:
Queue <element type> queue = new LinkedList <>();