991. Broken Calculator

On a broken calculator that has a number showing on its display, we can perform two operations:

  • Double: Multiply the number on the display by 2, or;
  • Decrement: Subtract 1 from the number on the display.

Initially, the calculator is displaying the number X.

Return the minimum number of operations needed to display the number Y.

Example 1:

Input: X = 2, Y = 3
Output: 2
Explanation: Use double operation and then decrement operation {2 -> 4 -> 3}.

Example 2:

Input: X = 5, Y = 8
Output: 2
Explanation: Use decrement and then double {5 -> 4 -> 8}.

Example 3:

Input: X = 3, Y = 10
Output: 3
Explanation:  Use double, decrement and double {3 -> 6 -> 5 -> 10}.

Example 4:

Input: X = 1024, Y = 1
Output: 1023
Explanation: Use decrement operations 1023 times.

Note:

  1. 1 <= X <= 10^9
  2. 1 <= Y <= 10^9

这道题说是有一个坏了的计算器,其实就显示一个数字X,现在我们有两种操作,一种乘以2操作,一种是减1操作,问最少需要多少次操作才能得到目标数字Y。好,现在来分析,由于X和Y的大小关系并不确定,最简单的当然是X和Y相等,就不需要另外的操作了。当X大于Y时,由于都是正数,肯定就不能再乘2了,所以此时直接就可以返回 X-Y。比较复杂的情况就是Y大于X的情况,此时X既可以减1,又可以乘以2,但是仔细想想,我们的最终目的应该是要减小Y,直至其小于等于X,就可以直接得到结果。这里X乘以2的效果就相当于Y除以2,操作数都一样,但是Y除以2时还要看Y的奇偶性,如果Y是偶数,那么 OK,可以直接除以2,若是奇数,需要将其变为偶数,由于X可以减1,等价过来就是Y加1,所以思路就有了,当Y大于X时进行循环,然后判断Y的奇偶性,若是偶数,直接除以2,若是奇数,则加1,当然此时结果 res 也要对应增加。循环退出后,还要加上 X-Y 的值即可,参见代码如下:

解法一:

class Solution {
public:
    int brokenCalc(int X, int Y) {
        int res = 0;
        while (Y > X) {
            Y = (Y % 2 == 0) ? Y / 2 : Y + 1;
            ++res;
        }
        return res + X - Y;
    }
};

若用递归来写就相当的简洁了,可以两行搞定,当然若你够 geek 的话,也可以压缩到一行,参见代码如下:

解法二:

class Solution {
public:
    int brokenCalc(int X, int Y) {
        if (X >= Y) return X - Y;
        return (Y % 2 == 0) ? (1 + brokenCalc(X, Y / 2)) : (1 + brokenCalc(X, Y + 1));
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/991

类似题目:

2 Keys Keyboard

参考资料:

https://leetcode.com/problems/broken-calculator/

https://leetcode.com/problems/broken-calculator/discuss/234484/JavaC%2B%2BPython-Change-Y-to-X-in-1-Line

https://leetcode.com/problems/broken-calculator/discuss/236565/Detailed-Proof-Of-Correctness-Greedy-Algorithm

LeetCode All in One 题目讲解汇总(持续更新中…)


转载请注明来源于 Grandyang 的博客 (grandyang.com),欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 grandyang@qq.com

💰


微信打赏


Venmo 打赏

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,试运营期间前五十位可享受半价优惠~)

×

Help us with donation