2059. 转化数字的最小运算数

2059. 转化数字的最小运算数

给你一个下标从 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 。

示例 1:

输入:nums = [1,3], start = 6, goal = 4
输出:2
解释:
可以按 6 → 7 → 4 的转化路径进行,只需执行下述 2 次运算:
- 6 ^ 1 = 7
- 7 ^ 3 = 4

示例 2:

输入:nums = [2,4,12], start = 2, goal = 12
输出:2
解释:
可以按 2 → 14 → 12 的转化路径进行,只需执行下述 2 次运算:
- 2 + 12 = 14
- 14 - 2 = 12

示例 3:

输入:nums = [3,5,7], start = 0, goal = -4
输出:2
解释:
可以按 0 → 3 → -4 的转化路径进行,只需执行下述 2 次运算:
- 0 + 3 = 3
- 3 - 7 = -4
注意,最后一步运算使 x 超过范围 0 <= x <= 1000 ,但该运算仍然可以生效。

示例 4:

输入:nums = [2,8,16], start = 0, goal = 1
输出:-1
解释:
无法将 0 转化为 1

示例 5:

输入:nums = [1], start = 0, goal = 3
输出:3
解释:
可以按 0 → 1 → 2 → 3 的转化路径进行,只需执行下述 3 次运算:
- 0 + 1 = 1 
- 1 + 1 = 2
- 2 + 1 = 3

提示:

  • 1 <= nums.length <= 1000
  • − 1 0 9 -10^9 109 <= nums[i], goal <= 1 0 9 10^9 109
  • 0 <= start <= 1000
  • start != goal
  • nums 中的所有整数互不相同

解题思路

利用队列完成广度优先搜索,并且使用set记录已经遍历过的元素,每次对于x进行如下操作

  • x + nums[i]
  • x - nums[i]
  • x ^ nums[i](按位异或 XOR)
    再将结果加入到队列里面,当运算结果越过 0 <= x <= 1000 范围,那么就不将其加入队列当中。

代码

class Solution {
public:
    int minimumOperations(vector<int> nums, int start, int goal) {

        queue<int> q;
        int d(1);
        q.push(start);
        unordered_set<int> s{start};
        while (q.size() != 0) {
            int len=q.size();
            for (int i = 0; i < len; ++i) {
                int  cur=q.front();
                q.pop();
                for (auto n:nums)
                {
                    if (goal==n+cur)
                        return d;
                    if (goal==cur-n)
                        return d;
                    if (goal==(cur^n))
                        return d;
                    if (cur+n<=1000&&cur+n>=0&&s.find(cur+n)==s.end())
                    {
                        q.push(cur+n);
                        s.insert(cur+n);
                    }
                    if (cur-n<=1000&&cur-n>=0&&s.find(cur-n)==s.end())
                    {
                        q.push(cur-n);
                        s.insert(cur-n);
                    }
                    if ((cur^n)<=1000&&(cur^n)>=0&&s.find(cur^n)==s.end())
                    {
                        q.push(cur^n);
                        s.insert(cur^n);
                    }
                }
            }
            d++;
        }
        return -1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值