【问题标题】:To reach the target number from 0 in minimum number of steps以最少步数从 0 达到目标数
【发布时间】:2017-09-11 16:13:03
【问题描述】:

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

这是我想出的逻辑:

最好的方法是向后工作。从你需要的号码开始:

  1. 如果数字是奇数,则减 1。
  2. 如果是偶数,则除以 2。
  3. 到零时停止。

例如,对于 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 问题,因此我无法更改函数定义或返回类型。这就是我在for 循环中从long 转换为int 的原因,以便使用%(模数)。我想知道我哪里出错了。我的算法计算时间是否太长(对于接近一百万的值的数量)?显然是这样,但是我如何更改我的算法以通过所有测试用例?

提前谢谢你:)

【问题讨论】:

  • 这被标记为 python 有什么原因吗?
  • 这也被标记在 python 下,因为我认为 python 可以提供更好的解决方案。所以,如果碰巧任何 python 人看到这段代码并说“我可以在几秒钟内降低时间复杂度”。所以是的......@Stael
  • 你得到了什么判决? TLE 还是 WA?
  • 演员阵容可能会导致问题。请参阅 here 以在 longs 上使用模数。
  • 我收到“因超时而终止”错误

标签: java python algorithm mathematical-optimization


【解决方案1】:
for (x = (int)kValues[i]; x != 0 ; ++steps)

您将 long 转换为 int 的事实非常可疑。当你这样做时,你可能会得到一个负数。

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

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

【讨论】:

  • 如果我这样做,我不能在我的逻辑中使用模数
  • @Prakhar 为什么? % 定义了很长时间。但您也可以简单地测试(num &amp; 1) == 0
【解决方案2】:

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

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;
}

【讨论】:

  • 不需要Ls。每当您使用带有 long 和 int 操作数的二元运算符时,int 将自动提升为 long。
【解决方案3】:

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

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

numberOfBits = Long.bitCount(x)
highBitNumber = floor(log2(x)) = 63 - Long.numberOfLeadingZeros(x)

如果值为零,highBitNumber 部分不起作用,因此 if 语句。

【讨论】:

    【解决方案4】:

    对于输入数字 x,

    最少数量操作数 = (int)log2(x) + Long.BitCount(x)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-11
      • 2022-10-07
      • 2020-04-17
      • 2019-01-08
      • 2020-03-26
      • 2022-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多