简体   繁体   English

交替 1 和 0 的最小数量

[英]Minimum number of Alternating 1 and 0

I want to find the minimum number of flips required to get an alternating of [0, 1, 0, 1] for example given [1, 1, 0, 1].我想找到获得 [0, 1, 0, 1] 交替所需的最小翻转次数,例如给定 [1, 1, 0, 1]。 so in this case, it is one flip.所以在这种情况下,它是一次翻转。

def solution(A):
    count = 0
    myDict = {}
    myDict[1] = True
    myDict[0] = False

    next = None
    # first element value
    val = myDict[A[0]]
    if val == True:
        next = False
    else:
        next = True

    for element in A[1:]:
        if next != myDict[element]:
            count += 1
            # do something to update element
            myDict[element] = next
        if myDict[element] == True:
            next = False
        else:
            next = True

    return count

My solution does not work for the input [1, 1, 0, 1, 1].我的解决方案不适用于输入 [1, 1, 0, 1, 1]。 Because it gives back 3 when the answer it should give back is 2(change the first index and last index elements to 0).因为当它应该返回的答案是 2 时它返回 3(将第一个索引和最后一个索引元素更改为 0)。 How can i solve this?我该如何解决这个问题?

You could just count the differences for each kind of pattern and take the min您可以计算每种模式的差异并取min

def minFlip(a):
    return min(
        sum(n == i % 2 for i, n in enumerate(a)),
        sum(n == (i + 1) % 2 for i, n in enumerate(a))
    )

minFlip([1, 1, 0, 1, 1])
#2
minFlip([0, 1, 0, 1, 0])
#0
minFlip([1, 1, 1, 1, 1])
#2
minFlip([0, 0, 0, 0, 0])
#2

You could count the values for which the least significant bit is different from that of the index.您可以计算最低有效位与索引不同的值。 Then take that count or the "opposite" (len-count):然后取那个计数或“相反”(len-count):

def minFlip(a):
    flips = sum((n ^ i) & 1 for i, n in enumerate(a))
    return min(flips, len(a)-flips)

Alternatively, you could sum up 1 and -1 depending on that bit, and then derive the solution from that:或者,您可以根据该位总结 1 和 -1,然后从中得出解决方案:

def minFlip(a):
    return (len(a)-abs(sum(-1 if (n^i)&1 else 1 for i,n in enumerate(a)))) // 2

(The number of flips to achieve an alternating pattern starting with 0) + (the number of flips to achieve an alternating pattern starting with 1) = (n: the number of elements in your list) (实现从 0 开始的交替模式的翻转次数)+(实现从 1 开始的交替模式的翻转次数)=(n:列表中的元素数)

So:所以:

  1. Find out how many flips it would take to achieve an alternating pattern starting with 0. Call this patt0 .找出实现从 0 开始的交替模式需要多少次翻转。称之为patt0
  2. patt1 = n - patt0
  3. ans = min(patt0, patt1)

So in your case, you found it took 3 flips for a list of 5, so ans = min(3, 5-3) which is 2 .因此,在您的情况下,您发现 5 的列表需要翻转 3 次,因此ans = min(3, 5-3)2

solution:解决方案:

  • pattern in the form of 0,1; 0,1 形式的模式; this can be set in the pattern这可以在模式中设置
  • loop input_values循环输入值
  • if is 1,3,5.. (odd element)如果是 1,3,5..(奇数元素)
    • if value is not false then add 1 to flips如果值不为假,则翻转加 1
  • if is 2,4,6 (even element)如果是 2,4,6(偶数元素)
    • if value is not true then add 1 to flips如果值不为真,则在翻转时加 1
  • return flips返回翻转
def getFlips(input_value):
  pattern = [False, True]
  flips = 0
  for i in range(len(input_value)):
    if i % 2 == 1:
      flips += (1 if input_value[i] != pattern[0] else 0)
    elif i % 2 == 0:
      flips += (1 if input_value[i] != pattern[1] else 0)
  return flips

example:例子:

print(getFlips([True, True, True, False])) == 1

For completeness, here's an O(1) space basic dynamic programming, not much different than other proposed solutions, but can be seen here to start outrunning the ones that use list comprehensions.为了完整起见,这里是一个O(1)空间基本动态规划,与其他提出的解决方案没有太大不同,但可以在这里看到开始超越使用列表推导式的解决方案。

def f(A):
  a, b = 0, 0
  for i in xrange(len(A)):
    m = i & 1 ^ A[i]
    a, b = m + a, (not m) + b
  return min(a, b)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM