题目描述:
给你一个下标从 0 开始的整数数组 nums ,该数组由 互不相同 的数字组成。另给你两个整数 start 和 goal 。
整数 x 的值最开始设为 start ,你打算执行一些运算使 x 转化为 goal 。你可以对数字 x 重复执行下述运算:
如果 0 <= x <= 1000 ,那么,对于数组中的任一下标 i(0 <= i < nums.length),可以将 x 设为下述任一值:
x + nums[i]
x - nums[i]
x ^ nums[i](按位异或 XOR)
注意,你可以按任意顺序使用每个 nums[i] 任意次。使 x 越过 0 <= x <= 1000 范围的运算同样可以生效,但该该运算执行后将不能执行其他运算。
返回将 x = start 转化为 goal 的最小操作数;如果无法完成转化,则返回 -1 。
方法一:
class Solution {
public:
int minimumOperations(vector<int>& nums, int start, int goal) {
vector<int> flag(1001, false); //记录出现过的状态,防止重复
flag[start] = true;
queue<int> que;
que.push(start);
int ans = 0; //最小操作数
while (!que.empty())
{
int n = que.size();
ans++; //bfs的每一层代表新的一次操作
for (int i = 0; i < n; i++)
{
int cur = que.front();
que.pop();
for (int j = 0; j < nums.size(); j++)
{
int a = cur + nums[j];
int b = cur - nums[j];
int c = cur ^ nums[j];
if (a == goal || b == goal || c == goal)
{
return ans;
}
if (a >= 0 && a <= 1000 && !flag[a]) //加法操作
{
que.push(a);
flag[a] = true;
}
if (b >= 0 && b <= 1000 && !flag[b]) //减法操作
{
que.push(b);
flag[b] = true;
}
if (b >= 0 && b <= 1000 && !flag[b]) //异或操作
{
que.push(b);
flag[b] = true;
}
}
}
}
return -1;
}
};
一开始用的dfs,但是调不出来,后面改用按照背包问题改成dp来写,卡在了第41个样例。。
最后看的别人的解法,原来用的是bfs,像这种求最优解的题目,用bfs肯定是比dfs好的,因为dfs在运算的过程中将会产生许多不必要的结果,这题就算dfs调试出来也是会超时的。
总结一下就是如果要寻找多种符合条件的解,那么就考虑是否用dfs;如果要找一个最优解,那么bfs的优先级肯定比dfs高。