📘 題目敘述
給你一個字串 s,只包含字元 '0' 和 '1'。在一次操作中,你可以把任意一個 '0' 變成 '1',或把 '1' 變成 '0'。
如果一個字串相鄰兩個字元都不相等,則稱它為交錯字串(alternating)。例如 "010" 是交錯字串,而 "0100" 不是。
請回傳把 s 變成交錯字串所需要的最少操作次數。
條件限制
1 <= s.length <= 10^4s[i]是'0'或'1'
🧠 解題思路
交錯字串其實只會有兩種可能的目標型態:
- 目標 A:
010101...(偶數位置是 0,奇數位置是 1) - 目標 B:
101010...(偶數位置是 1,奇數位置是 0)
我的做法是先計算「要變成目標 A 需要改幾個字元」,這個數量叫 c0。
因為每個位置不是符合目標 A 就是不符合,所以:
- 變成目標 B 需要修改的次數就會是
n - c0
最後答案就是 min(c0, n - c0)。
所有變數
n:字串s的長度c0:把s變成0101...這種型態時,需要修改的字元數ans:最後答案(程式中直接用min(c0, n - c0)回傳)
🪜 主要流程步驟
1. 設定其中一種目標型態:0101...
我把目標固定成:第 i 個位置應該是 i % 2(0,1,0,1...),用這個當作參考。
2. 掃過整個字串,計算 c0
如果某一格 s[i] 跟目標 i % 2 一樣,就代表「這一格已經符合 0101...」
我把符合的數量累加到 c0,最後:
- 不符合 0101... 的數量 =
n - c0 - 而「把字串變成 0101...」需要改的,就是不符合的數量
你這份程式的寫法是反過來:你累加的是「符合」的數量,最後用 min(c0, n - c0) 直接同時代表兩種目標的修改量,效果一樣。
3. 兩種目標取最小
0101... 和 1010... 兩種只差整體翻轉,所以修改次數必定一個是 c0,另一個是 n - c0,取最小即可。
⏱️ 複雜度
- 時間複雜度:
O(n)(掃一次字串) - 空間複雜度:
O(1)(只用常數變數)
💻 程式碼實作
class Solution {
public:
int minOperations(string s) {
int n = s.size();
int c0 = 0; // c0是01數列
for (int i = 0; i < n; i++) {
if (s[i] - '0' == i % 2) {
c0++;
}
}
return min(c0, n - c0);
}
};
🔗 題目連結
https://leetcode.com/problems/minimum-changes-to-make-alternating-binary-string/