给定一个二进制字符串,目标字符串中全为0

时间:2019-09-20 13:22:02

标签: java algorithm data-structures

给出一个表示目标状态的二进制字符串。将相同大小的二进制字符串(全为0)转换为目标状态所需的最少翻转次数。翻转还会导致所有正确的位被翻转。

例如

输入:00101(代表目标)

输出:3

说明:

00000 -> 00111 -> 00100 -> 00101

3 个答案:

答案 0 :(得分:1)

输入:00101(代表目标) 输出3 说明: 00000-> 00111-> 00100-> 00101

private fun castOrNull(anything: Any): String? {
return anything as? String  }

答案 1 :(得分:1)

谢谢@Primusa的回答。以下是@Primusa答案的Java代码:

    public static int getFlipsCount(String s) {
        int result = 0;
        int[] arr = new int[s.length()];
        for (int i = 0; i < s.length(); i++) {
            arr[i] = Integer.valueOf(s.charAt(i) + "");
        }
        for (int i = 0; i < arr.length; i++) {
            result += (result % 2) ^ arr[i];
        }
        return result;
    }

答案 2 :(得分:0)

两个观察结果:

  1. 翻转是可交换的。无论您按什么顺序进行操作,您都将获得相同的结果。

  2. 在某些时候,您必须翻转不匹配的最高有效位

这给了我们一个方便的贪婪论点。通过翻转需要翻转的最左边的位,我们将始终获得最佳解决方案。在某些时候,我们必须翻转一下,顺序并不重要,所以我们最好先做一下。

将其实现为O(N)可能会很棘手-如果我们天真地翻转所有内容,我们最终会进行O(N)翻转,从而提供了O(N^2)解决方案。我们可以注意到,在确定当前位的真实值时,我们只关心已经发生的翻转次数。如果该数字为奇数,则该位的值将被翻转。否则它将保持不变。

我们可以进行最后的观察,以使生活更加轻松:

  1. 翻转相互抵消。我们不问从0到达目标需要多少次翻转,而是要询问从目标到0需要多少次翻转。只要位的真实值不等于0,我们只需添加一次翻转。

伪代码:

result = 0
// most to least significant
for bit in bits:
    if result%2 == 0:
        if bit != 0: result += 1
    else:
        if not bit != 0: result += 1
print(result)

更简洁地说:

bits = [0, 0, 1, 0, 1]
result = 0
for bit in bits: result += (result%2)^bit
print(result)

输出:

3