每日一题-力扣(leetcode)2059. 转化数字的最小运算数
阿里云国际版折扣https://www.yundadi.com |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
题目描述
给你一个下标从 0 开始的整数数组 nums 该数组由 互不相同 的数字组成。另给你两个整数 start 和 goal 。
整数 x 的值最开始设为 start 你打算执行一些运算使 x 转化为 goal 。你可以对数字 x 重复执行下述运算
如果 0 <= x <= 1000 那么对于数组中的任一下标 i0 <= i < nums.length可以将 x 设为下述任一值
x + nums[i]
x - nums[i]
x ^ nums[i]按位异或 XOR
注意你可以按任意顺序使用每个 nums[i] 任意次。使 x 越过 0 <= x <= 1000 范围的运算同样可以生效但该该运算执行后将不能执行其他运算。
返回将 x = start 转化为 goal 的最小操作数如果无法完成转化则返回 -1 。
示例 1
输入nums = [2,4,12], start = 2, goal = 12
输出2
解释
可以按 2 → 14 → 12 的转化路径进行只需执行下述 2 次运算
- 2 + 12 = 14
- 14 - 2 = 12
示例2
输入nums = [3,5,7], start = 0, goal = -4
输出2
解释
可以按 0 → 3 → -4 的转化路径进行只需执行下述 2 次运算
- 0 + 3 = 3
- 3 - 7 = -4
注意最后一步运算使 x 超过范围 0 <= x <= 1000 但该运算仍然可以生效。
示例 3
输入nums = [2,8,16], start = 0, goal = 1
输出-1
解释
无法将 0 转化为 1
算法思路
这题一开始想复杂了直接上手就dfs同时也没注意到 “x 越过 0 <= x <= 1000 范围的运算同样可以生效但该该运算执行后将不能执行其他运算。” 这个条件所以导致我卡了很久一直超时没跑过去最后参考了一位大佬的解法才顺利AC出来。
看到最短路径、最小次数这类问题应当考虑BFS然后这道题就变成了从start到goal的最短路径问题然后我们用set记录一下已访问的数防止重复访问然后遇到不是在0 - 1000 内的数就不用push到queue中。
AC代码如下
class Solution {
public:
int minimumOperations(vector<int>& nums, int start, int goal) {
queue<int>q;
set<int>visited;
q.push(start);
int ans = 0;
while(!q.empty()) {
int length = q.size();
for(int i = 0; i < length; i++) {
int top = q.front();
q.pop();
if(top == goal) return ans;
if(top < 0 || top > 1000 || visited.count(top) != 0) continue;
for(auto i : nums) {
q.push(top + i);
q.push(top - i);
q.push(top ^ i);
}
visited.insert(top);
}
ans++;
}
return -1;
}
};