小能豆

使二进制字符串全为 1 的最少双重或三重翻转次数

py

我刚刚完成了一次编程面试,其中有一道题让我很困惑。虽然面试已经结束了,但我还是很想知道这道题该怎么解。

问题:给定一个二进制字符串(仅包含"1""0"),找出获得所有 s 的二进制字符串所需的最少翻转次数"1"

  • 当执行翻转时,该索引处的值将从"0"变为"1""1"变为"0"
  • 您唯一可以进行的翻转是双翻转或三翻转。这意味着,在进行翻转时,必须对两个或三个相邻的索引进行翻转。

例子:

  • 对于二进制字符串"1010",所需的最小翻转次数为 2。"1010"=> "1001"=> "1111"(结束)
  • 对于"10001",所需的最少翻转次数为 1。"10001"=> "11111"(结束)

阅读 21

收藏
2025-01-06

共1个答案

小能豆

您可以使用递归来强制执行它,通过对前 2/3 个字符执行翻转并将递归结果与下一个位置相加:

def minFlips(s):
     if "0" not in s:      return 0  # all 1s, no flip needed
     if s in ("00","000"): return 1  # last flip for whole string

     def flip(n): # flip 1st n bits
          return s[:n].translate({48:49,49:48})+s[n:]

     result = [float('inf')] # track minimum flips
     if s.startswith("0"):   # must flip if starting with a zero
         if len(s)>2:        # first 2 + recursion
             result.append(1+minFlips(flip(2)[1:])) 
         if len(s)>3:        # first 3 + recursion
             result.append(1+minFlips(flip(3)[1:])) 
     else: # starts with "1"
         result.append(minFlips(s[1:])) # 0 flip + recursion
         if "0" in s[:2]: # can flip zero at 2nd position
             result.append(1+minFlips(flip(2))) # first 2 + recursion
         if "0" in s[:3]: # can flip zero at 2nd or 3rd position
             result.append(1+minFlips(flip(3))) # first 3 + recursion
     return min(result)

print(minFlips("1010"))       # 2
print(minFlips("10001"))      # 1
print(minFlips("1010110101")) # 4

为了优化这一点,您可以使用记忆法,或者添加@lru_cache()装饰器(来自 functools)

2025-01-06