1345. Jump Game IV

定义dp[i]为从i->end,最短路径长度。
直接用dfs,由于有圈的存在,所以,每个点作为中间点的dp[i]和最为开始点的dp[]是不同的。所有都要逐一遍历,很慢。

看了答案,才知道BFS才是最快的,首先,成环的部分,深度是无限大的。我们只用返回深度最小的就可以了。
如果这个点已经走过了,那么后面就不用再走了,因为它一定是最短的。

因此,对于有环走点问题,采用BFS是最优的。同时,它还需要贪心,index大的,一定比index小的优先级要高一些。

class Solution {
public:
    // 有圈的dfs,需要设置一下
    // 计算一个点的dfs,需要不考虑??
    // 但是每个点都走一遍又一遍,还是太慢了。破解之道呢??
    // 看了答案,原来破解之道是用bfs,因为有圈的话,会在没圈前就跳出来。
    // 但是对于太长的还是有问题,所以从最大的开始
    int minJumps(vector<int>& arr) {
        // gain num to id
        map<int, vector<int>> num2pos;
        for(int i=arr.size()-1;i>=0;i--){
            if (num2pos.find(arr[i])==num2pos.end()){
                vector<int> temp(1,i);
                num2pos[arr[i]] = temp;
            }
            else{
                num2pos[arr[i]].push_back(i);
            }
        }
        
        int step = 0;
        queue<int> q;
        q.push(0);
        vector<int> visit(arr.size(), 0);
        visit[0] = 1;
        if (arr.size()==1){return step;}
        while(1){// must has results
            step++; // 1
            int totalnum = q.size();
            for(int i=0;i<totalnum;i++){
                int pos = q.front(); // 0
                q.pop();
                
                // for pos+1
                if(pos+1<arr.size()){
                    if (pos+1==arr.size()-1){return step;}
                    if (visit[pos+1]==0){
                        visit[pos+1] = 1;
                        q.push(pos+1);
                    }
                }
                // for pos-1
                if(pos-1>=0){
                    if (pos-1==arr.size()-1){return step;}
                    if (visit[pos-1]==0){
                        visit[pos-1] = 1;
                        q.push(pos-1);
                    }
                }
                // for same val
                vector<int> poss = num2pos[arr[pos]];
                for(int jj=0;jj<poss.size();jj++){
                    int pos = poss[jj];
                    if (pos==arr.size()-1){return step;}
                    if (visit[pos]==0){
                        visit[pos] = 1;
                        q.push(pos);
                    }
                }
                
            }
        }
        cout<<"error!!"<<endl;
        
    }
};


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值