问题:
跳棋问题。
给定跳棋一维数组arr
arr[i]代表到达位置 i 后,能够向前or向后移动的步数
即,下一个位置为:i+arr[i] or i-arr[i]
⚠️ 注意:这里下个位置不能超出arr范围。
求从给定Start位置开始,是否能最终走到arr[x]==0的位置。
Example 1:
Input: arr = [4,2,3,0,3,1,2], start = 5
Output: true
Explanation:
All possible ways to reach at index 3 with value 0 are:
index 5 -> index 4 -> index 1 -> index 3
index 5 -> index 6 -> index 4 -> index 1 -> index 3
Example 2:
Input: arr = [4,2,3,0,3,1,2], start = 0
Output: true
Explanation:
One possible way to reach at index 3 with value 0 is:
index 0 -> index 4 -> index 1 -> index 3
Example 3:
Input: arr = [3,0,2,1,2], start = 2
Output: false
Explanation: There is no way to reach at index 1 with value 0.
Constraints:
1 <= arr.length <= 5 * 104
0 <= arr[i] < arr.length
0 <= start < arr.length
解法:BFS
- 状态:位置 idx
- queue中保存元素即为 idx,visited也需要记录idx,这里可以使用对arr直接赋值为-1,来节省空间复杂度。
- ⚠️ 注意:由于需要对arr赋值,那么需要等到arr的值不再被使用后,再进行赋值。
- 即,在queue.pop后,并获得下一步后,才能对cur的arr值进行赋值=-1。
- 选择:
- 限制:下个位置不超出边界 && 下个位置未访问过arr[next]!=-1
- 向前移动arr[cur]:下一个位置:cur+arr[cur]
- 向后移的arr[cur]:下一个位置:cur-arr[cur]
- 结束条件:
- arr[cur]==0
代码参考:
class Solution {
public:
bool canReach(vector<int>& arr, int start) {
bool res = false;
queue<int> q;
q.push(start);
while(!q.empty()) {
int cur = q.front();
q.pop();
//cout<<"pop:"<<cur<<" value:"<<arr[cur]<<endl;
if(arr[cur]==0) return true;
int next = cur+arr[cur];
if(next>=0 && next<arr.size() && arr[next]!=-1) {
q.push(next);
//cout<<"push:"<<next<<" value:"<<arr[next]<<endl;
}
next = cur-arr[cur];
if(next>=0 && next<arr.size() && arr[next]!=-1) {
q.push(next);
//cout<<"push:"<<next<<" value:"<<arr[next]<<endl;
}
arr[cur] = -1;
}
return false;
}
};