leetcode5916.转化数字的最小运算数(周赛,中等)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
自己没思路。。。

难点:
1.到达一个数字一遍后(nums.size() × 3进行扩散后),第二次到达该数字后,就不用再扩散了,因为跟之前效果一样,而且次数还更多了,所以第二次之后就没必要了,没想到vis数组!!!
2.题目中有一个条件:
(1)->元素互不相等,也就是需要进行nums.size() × 3进行扩散,否则需要先去重!!!
(2)->超过1000的数字不能再使用数组中的元素进行扩散->目的是防止队列元素过多爆炸!!!

思路:遇到最少次数->BFS
细节: 每次把到达的数字放入队列,按照nums.size() × 3进行扩散,扩散到的数字下次扩散的时候就不用继续放入队列了。
总结:
1.遇到从一个值,到另外一个值最小操作次数的题目,要想到BFS
2.难点在于判断广搜的终止条件:这道题是超过1000!!!
3.用DFS的话,一条一路路径都搜索一遍,不断更新ans,复杂度高,最短路径的题还是要用BFS

class Solution {
public:
    int minimumOperations(vector<int>& nums, int start, int goal) {
		
        //中间到达过的数字,之后就不用再搜索了,因为操作都是一样的,而且题目问的是最短次数,所以到达过该数字之后更没必要了
        vector<bool> vis(1005);  //优化,改成bool类型!!!
        queue<pair<int, int>> q; 
        q.push(make_pair(start, 0));
        vis[start] = true;
        while (!q.empty()) {
            auto fr = q.front();
            q.pop();
            if (fr.first == goal) return fr.second;
            //if (fr.first > 1000 || fr.first < 0) continue; //不满足尽量不入队!!!
            for (auto &each : nums) {
                if (fr.first + each >= 0 && fr.first + each <= 1000) {
                    if (!vis[fr.first + each]) {
                        vis[fr.first + each] = true;
                        q.push(make_pair(fr.first + each, fr.second + 1));
                    }
                }else if (fr.first + each == goal) return fr.second + 1;
                    //q.push(make_pair(fr.first + each, fr.second + 1)); //优化,不满足的尽量就不入队!!!

                if (fr.first - each >= 0 && fr.first - each <= 1000) {
                    if (!vis[fr.first - each]) {
                        vis[fr.first - each] = true;
                        q.push(make_pair(fr.first - each, fr.second + 1));
                    }
                }else if (fr.first - each == goal) return fr.second + 1;

                if ((fr.first ^ each) >= 0 && (fr.first ^ each) <= 1000) { //加括号!!!
                    if (!vis[fr.first ^ each]) {
                        vis[fr.first ^ each] = true;
                        q.push(make_pair(fr.first ^ each, fr.second + 1));
                    }
                }else  if ((fr.first ^ each) == goal) return fr.second + 1;
            }
        }
        return -1;
    }
};

优化:
不满足的尽量就不入队,对时间影响特别大!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值