我刚刚完成了一次编程面试,其中有一道题让我很困惑。虽然面试已经结束了,但我还是很想知道这道题该怎么解。
问题:给定一个二进制字符串(仅包含"1"或"0"),找出获得所有 s 的二进制字符串所需的最少翻转次数"1"。
"1"
"0"
例子:
"1010"
"1001"
"1111"
"10001"
"11111"
您可以使用递归来强制执行它,通过对前 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)
@lru_cache()