1306. Jump Game III
问题:
跳棋问题。
给定跳棋一维数组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
代码参考:
1 class Solution { 2 public: 3 bool canReach(vector<int>& arr, int start) { 4 bool res = false; 5 queue<int> q; 6 q.push(start); 7 while(!q.empty()) { 8 int cur = q.front(); 9 q.pop(); 10 //cout<<"pop:"<<cur<<" value:"<<arr[cur]<<endl; 11 if(arr[cur]==0) return true; 12 int next = cur+arr[cur]; 13 if(next>=0 && next<arr.size() && arr[next]!=-1) { 14 q.push(next); 15 //cout<<"push:"<<next<<" value:"<<arr[next]<<endl; 16 } 17 next = cur-arr[cur]; 18 if(next>=0 && next<arr.size() && arr[next]!=-1) { 19 q.push(next); 20 //cout<<"push:"<<next<<" value:"<<arr[next]<<endl; 21 } 22 arr[cur] = -1; 23 } 24 return false; 25 } 26 };