以最小步数从0到达目标数

时间:2017-09-11 16:13:03

标签: java python algorithm mathematical-optimization

问题陈述: 找到从0(零)到达目标数x所需的最小步数,仅使用两个操作:+ 1 (对数字加1)或* 2 (乘以2数字)

所以这就是我提出的逻辑:

最好的方法是倒退。从您需要的号码开始:

  1. 如果数字为奇数,则减去1。
  2. 如果数字均匀则除以2。
  3. 当你达到零时停止。
  4. 例如,对于29,你得到28,14,7,6,3,2,1,0。

    而且,这是我尝试过的(Java 7):

    kValues是一个数组,其x值需要计算steps并存储在名为result的数组中。

    static int[] countOperationsToK(long[] kValues) {
        int size = kValues.length,x,i,steps;
        int result[] = new int[size];
    
        for (i = 0; i < size; ++i)
        {
            steps = 0;
            for (x = (int)kValues[i]; x != 0 ; ++steps)
            {
                if((x % 2) == 0)
                    x /= 2;
                else x--;
            }
            result[i] = steps;
        }
    
        return result;
    }
    

    我的问题:

    这是一个Hackerrank问题,我应该写一个有效的代码。我在7/11测试用例中取得了成功,其他人则超时了。既然,这是一个Hackerrank问题,我无法更改函数定义或返回类型。这就是我在long循环中从int转换为for的原因,以便使用%(模数)。我想知道我哪里出错了。我的算法计算时间太长(对于接近一百万的值的数量)?显然是这种情况,但如何更改算法以通过所有测试用例?

    提前谢谢你:)

4 个答案:

答案 0 :(得分:1)

for (x = (int)kValues[i]; x != 0 ; ++steps)

你向int转换一个长的事实是非常可疑的。当你这样做时,你可能得到一个负数。

说出x == -2:您将其除以2以得到-1,然后减去1得到-2。你会无限期地继续这样做。

只需将x定义为long,然后移除演员。

答案 1 :(得分:0)

所以,这是工作代码。我忘了在使用模数时附加L。愚蠢的错误导致了很多打字。 LOL !!

static int[] countOperationsToK(long[] kValues) {
    int size = kValues.length,i,steps;
    int result[] = new int[size];
    long x;

    for (i = 0; i < size; ++i)
    {
        steps = 0;
        for (x = kValues[i]; x != 0 ; ++steps)
        {
            if((x % 2L) == 0)
                x /= 2L;
            else x -= 1L;
        }
        result[i] = steps;
    }

    return result;
}

答案 2 :(得分:0)

这是一个非常短的版本,使用位分析:

static int[] countOperationsToK(long... input) {
    int result[] = new int[input.length];
    for (int i = 0; i < input.length; i++)
        if (input[i] > 0)
            result[i] = Long.bitCount(input[i]) + 63 - Long.numberOfLeadingZeros(input[i]);
    return result;
}

这里的想法是查看二进制数,例如对于29 11101。有4位设置,所以我们需要做+1四次,最高位位是4,所以我们需要左移(即*2)四次,总共8个操作:+1*2+1*2+1*2*2,{{1} }。

+1

如果值为零,则numberOfBits = Long.bitCount(x) highBitNumber = floor(log2(x)) = 63 - Long.numberOfLeadingZeros(x) 部分不起作用,因此highBitNumber语句。

答案 3 :(得分:0)

对于输入数字x,

最小编号操作数=(int)log2(x)+ Long.BitCount(x)