解題說明
Minimum Flips to Make a OR b Equal to c
題目描述:給定三個正整數 a、b、c,每次操作可以翻轉 a 或 b 中任意一個 bit(0 變 1 或 1 變 0),求讓 a OR b == c 所需的最少翻轉次數。
解題思路:逐 bit 分析三個數字的對應位,共有兩種情況:① c 的該位為 1:需要 a 或 b 中至少有一個 1,若兩者都是 0 則需要翻轉 1 次;② c 的該位為 0:需要 a 和 b 的該位都是 0,若 a=1 且 b=1 需翻轉 2 次,若只有一個是 1 則需翻轉 1 次。對 32 個 bit 逐一掃描,累加所需翻轉次數即得答案。
C++ 解法
複雜度分析
時間複雜度:O(1) — 固定迴圈 32 次(整數位元數),常數時間。
空間複雜度:O(1) — 只使用常數個變數。
虛擬碼
1. Initialize flips = 0
2. For i from 0 to 31:
a. Extract bits: ba = (a>>i)&1, bb = (b>>i)&1, bc = (c>>i)&1
b. If bc == 1:
- If ba == 0 AND bb == 0: flips += 1
c. Else (bc == 0):
- flips += ba + bb
3. Return flips其他解法
整體位元運算(一次性):可以用公式 need_flip_for_zero = (a | b) & ~c(bc=0 但 a|b=1 的位)和 need_flip_for_one = ~(a | b) & c(bc=1 但 a|b=0 的位),但 bc=0 時若 a=1 且 b=1 需要翻轉 2 次,這需要額外計算 both_one = a & b & ~c 的 popcount 並加一次。整合後:flips = popcount(~(a|b) & c) + popcount((a|b) & ~c) + popcount(a & b & ~c)。
模擬所有 bit 對:與主解法邏輯相同,只是用 __builtin_popcount 對整個數字計算,程式碼更簡潔。
延伸思考
- 如果操作改為翻轉
a、b或c中的任一 bit,使a OR b == c,最少翻轉次數會如何改變? - 將 OR 改為 AND,即讓
a AND b == c,翻轉邏輯應如何調整? - 如何用一行位元運算(不使用迴圈)計算答案?