zoukankan      html  css  js  c++  java
  • [LeetCode 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

    This problem shares the exact same principle with the following related problem:  Going forward from X to Y is incorrect. We need to go backward from Y to X.

    Counter example: X = 3, Y = 10.

    Incorrect forward sequence of cost 4: 3 -> 6 -> 12 -> 11 -> 10;

    Correct forward sequence of cost 3: 3 -> 6 -> 5 -> 10;

    Incorrect Solution

    class Solution {
        public int brokenCalc(int X, int Y) {
            if(X >= Y) {
                return X - Y;
            }
            int op = 0;
            while(X < Y) {
                X *= 2;
                op++;
            }
            while(X != Y) {
                X--;
                op++;
            }
            return op;
        }
    }

    Correct Solution 

    class Solution {
        public int brokenCalc(int X, int Y) {
            //if X >= Y, we can only use decrement
            if(X >= Y) {
                return X - Y;
            }
            int op = 0;
            while(Y > X) {
                //if Y is odd, it means that we would go from a smaller value (Y + 1) / 2 to Y + 1, which is even, 
                //then perform a decrement to reach Y. 
                if(Y % 2 != 0) {
                    Y++;
                    op++;
                }
                //Y is even, it means that we would go from Y / 2 by double operation 
                Y /= 2;
                op++;
            }
            //X - Y represents the decrement operations we need to perform at the beginning 
            return op + (X - Y);
        }
    }

    TLE BFS solution

    The runtime of the above solution is O(logY). However since we are looking for the minimum number of operations, each operation can be considered as a graph node hop, we can use BFS to solve this problem. For Y that is O(10^6), it can compute the correct answer within the time limit. For bigger Y, this solution falls off since it takes O(Y) time and space.

    class Solution {
        public int brokenCalc(int X, int Y) {
            if(X >= Y) {
                return X - Y;
            }
            Deque<Integer> q = new ArrayDeque<>();
            Set<Integer> visited = new HashSet<>();
            q.addLast(X);
            visited.add(X);
            
            int op = 0;
            boolean reach = false;
            while(true) {
                int sz = q.size();
                for(int i = 0; i < sz; i++) {
                    int v = q.pollFirst();
                    if(v == Y) {
                        reach = true;
                        break;
                    }
                    if(v < Y) {
                        long u = (long)v * 2;
                        if(u < Integer.MAX_VALUE && !visited.contains((int)u)) {
                            q.addLast((int)u);
                            visited.add((int)u);
                        }
                    }
                    if(v - 1 > 0 && !visited.contains(v - 1)) {
                        q.addLast(v - 1);
                        visited.add(v - 1);
                    }
                }
                if(reach) {
                    break;
                }
                op++;
            }
            return op;
        }
    }

    Related Problems

    [LeetCode 1558] Minimum Numbers of Function Calls to Make Target Array

  • 相关阅读:
    .NET Core依赖注入集成Dynamic Proxy
    MediatR-进程内的消息通信框架
    03-EF Core笔记之查询数据
    02-EF Core笔记之保存数据
    01-EF Core笔记之创建模型
    EF Core 基础知识
    CQRS+ES项目解析-Equinox
    CQRS+ES项目解析-Diary.CQRS
    不要让事实妨碍好故事:Facebook精准广告产品与硅谷创业揭秘,4星奇书《混乱的猴子》
    会讲故事的前物理学家万维钢解读、推荐过的书24本,好书一半
  • 原文地址:https://www.cnblogs.com/lz87/p/10360822.html
Copyright © 2011-2022 走看看