【问题标题】:Given an array of size n containing 0's and 1's and two operations, find the minimum number of operations to make all elements as 0给定一个包含 0 和 1 以及两个操作的大小为 n 的数组,找到使所有元素为 0 的最小操作数
【发布时间】:2019-05-27 01:26:14
【问题描述】:

给定一个大小为 n 的数组,包含 0 和 1 以及两个操作,找出使所有元素为 0 的最小操作数。

操作:

  1. 如果第 (i+1) 个元素为 1,并且从第 (i+2) 个到所有连续元素为 0 或不存在(如果 i+2 = n),则翻转第 i 个元素。 (0

    例如,上述操作适用于:

在这个元素上

|

V   

1100

在这个元素上

  |

  V   

1011

  1. 没有任何限制地翻转第 n 个元素。

n

例如 输入: 1,0,0,0

输出: 15

解释:

1000 -> 1001 -> 1011 -> 1010 -> 1110 -> 1111 -> 1101 -> 1100 -> 0100 -> 0101 -> 0111 -> 0110 -> 0010 -> 0011 -> 0001 -> 0000

【问题讨论】:

  • 为什么不能把第一个 1 翻转为 0(第二条规则,没有任何限制)?只需一次操作
  • @AndrewScott 第二条规则仅适用于最后一位 (nth)。对 OP:n 的限制是多少?
  • @user3386109 是的。 OP应该澄清问题陈述
  • @GeorgiGerganov 抱歉,我撤回了我的评论,因为我想到有第 n 个元素,但索引 n 处没有元素。我同意 OP 应该澄清问题陈述。
  • @Dharsam1990 请同时添加 n 的限制以及运行时间限制(如果有)。

标签: algorithm bit-manipulation


【解决方案1】:

在除了所有0s 的数组之外的任何数组上,只有两个操作是可能的。翻转第 n 个元素或翻转数组中最后一个 1 之前的元素。
我们不需要考虑只有第一个元素是1 的边缘情况,因为我们可以在数组的开头添加任意数量的零并且它不会改变结果,即[1, 0, 0, 0][0, 1, 0, 0, 0]需要相同数量的最小操作才能成为全部 0s。
这意味着在01s 的每个序列中,其中一个操作将更接近0s,而另一个操作将更进一步。
这些观察的结果是,我们实际上有一个与二进制非常相似的数字系统,每个操作都可以看作是将数字递增或递减 1,这意味着对于 0s 和 1s 的每个序列都有一个等效的二进制数和十进制数,即此数与 0 之间的步数。
我发现这个系统和二进制之间的关系是这样的:
如果我们从头到尾遍历数组并翻转 1 之后的每个元素,我们会得到等效的二进制文件。这个操作需要在适当的地方完成,这意味着我们在迭代时改变数组本身,并且每次迭代的结果都会影响下一次迭代。我没有证据证明这是正确的,也许有人可以提供证据。

话虽如此,算法本身很简单。这是在python中:

a = [1, 0, 0, 0]

# convert to equivalent binary
for i in range(1, len(a)):
    a[i] = int(not a[i]) if a[i-1] == 1 else a[i]

# convert to decimal
bin_str = ''.join(map(str, a))
print(int(bin_str, 2))

【讨论】:

  • 非常有趣。该解决方案似乎提供了正确的答案。如何证明@jal_a 的观察真的很有趣。
  • 我认为该解决方案会奏效。但不确定如何证明正确性。不过,感谢@jal_a 的观察。
  • @Dharsam1990 我会尝试归纳,因为这是一个数字序列。
  • 问题中的序列遵循gray code 的模式。此答案中的代码转换为gray code to binary
  • @user3386109 这很有趣。有启发性的评论!
猜你喜欢
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
  • 2013-01-15
  • 2020-07-19
  • 2020-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多