【教3妹学编程-算法题】使 X 和 Y 相等的最少操作次数

瑟瑟发抖

2哥 : 叮铃铃,3妹,过年干嘛呢,是不是逛吃逛吃,有没有长胖呢。
3妹:切,我妈张罗着要给我相亲呢。
2哥 : 相亲?哈哈哈哈
3妹:别笑了,我妈说跟我年龄相等的人都已经孩子上小学了,跟她年龄相等的人孙子最少都会打酱油了。
2哥 :哈哈哈哈,让我先笑一会儿
3妹:话说2哥过年在家里也刷题吗?
2哥:当然了,雷打不动。
3妹:好吧,我有几天懈怠了。
2哥:好吧,说到刷题啊,今天有一道“相等”、“最少”的题目, 让我们先做一下吧~

吃瓜

题目:

给你两个正整数 x 和 y 。

一次操作中,你可以执行以下四种操作之一:

如果 x 是 11 的倍数,将 x 除以 11 。
如果 x 是 5 的倍数,将 x 除以 5 。
将 x 减 1 。
将 x 加 1 。
请你返回让 x 和 y 相等的 最少 操作次数。

示例 1:

输入:x = 26, y = 1
输出:3
解释:我们可以通过以下操作将 26 变为 1 :

  1. 将 x 减 1
  2. 将 x 除以 5
  3. 将 x 除以 5
    将 26 变为 1 最少需要 3 次操作。
    示例 2:

输入:x = 54, y = 2
输出:4
解释:我们可以通过以下操作将 54 变为 2 :

  1. 将 x 加 1
  2. 将 x 除以 11
  3. 将 x 除以 5
  4. 将 x 加 1
    将 54 变为 2 最少需要 4 次操作。
    示例 3:

输入:x = 25, y = 30
输出:5
解释:我们可以通过以下操作将 25 变为 30 :

  1. 将 x 加 1
  2. 将 x 加 1
  3. 将 x 加 1
  4. 将 x 加 1
  5. 将 x 加 1
    将 25 变为 30 最少需要 5 次操作。

提示:

1 <= x, y <= 10^4

思路:

思考
设 nums\textit{nums}nums 的异或和为 sss。

BFS,
每个操作都可以理解成:从 x 向操作后的数连边。

在这张图上跑 BFS,求出从 x 到 y 的最短路,即为答案。

注意,如果 x<y 那么只能用加一操作,此时可以直接算出操作次数。

java代码:

class Solution {
    public int minimumOperationsToMakeEqual(int x, int y) {
        if (x <= y) {
            return y - x;
        }
        int ans = x - y; // 总操作次数不会超过 x-y
        boolean[] vis = new boolean[x + ans + 1]; // +1 操作至多执行 x-y 次
        vis[x] = true;
        List<Integer> q = List.of(x);
        int step = 0;
        while (true) {
            List<Integer> tmp = q;
            q = new ArrayList<>();
            for (int v : tmp) {
                if (v == y) {
                    return Math.min(ans, step);
                }
                if (v < y) {
                    ans = Math.min(ans, step + y - v);
                    continue;
                }
                if (v % 11 == 0 && !vis[v / 11]) {
                    vis[v / 11] = true;
                    q.add(v / 11);
                }
                if (v % 5 == 0 && !vis[v / 5]) {
                    vis[v / 5] = true;
                    q.add(v / 5);
                }
                if (!vis[v - 1]) {
                    vis[v - 1] = true;
                    q.add(v - 1);
                }
                if (!vis[v + 1]) {
                    vis[v + 1] = true;
                    q.add(v + 1);
                }
            }
            step++;
        }
    }
}

  • 24
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值