思路:BFS
细节: 每次把到达的数字放入队列,按照nums.size() × 3进行扩散,扩散到的数字下次扩散的时候就不用继续放入队列了。
总结:
1.遇到从一个值,到另外一个值最小操作次数的题目,要想到BFS
2.难点在于判断广搜的终止条件:这道题是超过1000!!!
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;
}
};
优化:
不满足的尽量就不入队,对时间影响特别大!!!