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

 

代码参考:

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;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值