Thinking Backwards (LeetCode #991)

Approaching a problem in the standard way, or the way the problem asks you is not always the optimal solution. Sometimes it is best for us to think out of the box. Just like solving a maze, sometimes we find it easier by connecting the start and finish when we actually start at the finish point.


LeetCode #991

There is a broken calculator that has the integer startValue on its display initially. In one operation, you can:

  • multiply the number on display by 2, or
  • subtract 1 from the number on display.

Given two integers startValue and target, return the minimum number of operations needed to display target on the calculator.

The first approach that comes to mind is to use recursion and try to approach the target by the two operations above. To decide which to use, we simply check that which operation brings us closer to the target.

class Solution {
public:
    int brokenCalc(int startValue, int target) {
        if(startValue == target)
            return 0;
        else if(startValue >= target / 2.0)
            return 1 + brokenCalc(startValue - 1, target);
        return 1 + brokenCalc(2 * startValue, target);
    }
};

However, not only does the code above would result in a TLE, it does not yield the optimal result. Take (5, 8) for an example:

When we first decide which operation to use, we would choose the times 2 one and then just complete two more subtractions to get the 8 we want, totaling in 3 operations. However, if we were to first subtract 1 from 5 and then multiply the number by 2, we would get the 8 with 1 less step. Now, this raises a question, is the way we choose which operation to use actually optimal?

Obviously, the answer is no, and there is no feasible way of finding out the best solution if we are approaching the problem in this way.


The way we approach this is backward. We have to make our result as close to our starting value. Since it is reversed, the two operations will be:

1) Divide the target by 2

2) Add 1 to the target

All we need to do is keep on dividing the target until it is smaller or equal to the starting value. If the target is odd, we will add one first and then carry on with the division. Finally, we will just complete the result by continuously adding one to the target until they are equal:

class Solution {
public:
    int brokenCalc(int startValue, int target) {
        int count = 0;
        while(target > startValue){
            if(target % 2) 
                target++;
            else
                target /= 2;
            count ++;
        }
        return count + startValue - target;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值