題目連結:
題目意譯:
你被給定一個索引值從 0 開始數且長度為 n 的二元字串 target。你有另一個長度同為 n 的二元字串 s,其一開始初始化為只包含 0。你想要讓 s 變得跟 target 一樣。
在一次操作中,你可以挑一個索引值 i,其中 0 ≦ i < n,來使得閉區間 [i, n - 1] 的位置上所有位元都翻轉。「翻轉」代表著將 '0' 變成 '1',而 '1' 變成 '0'。
回傳使 s 變得跟 target 一樣最少所需之操作數。
限制:
n == target.length
1 ≦ n ≦ 10 ^ 5
target[i] 只會是 '0' 或是 '1'。
範例測資:
範例 1:
輸入: target = "10111"
輸出: 3
解釋: 一開始,s = "00000"。
選擇索引值 i = 2:"00000" -> "00111"
選擇索引值 i = 0:"00111" -> "11000"
選擇索引值 i = 1:"11000" -> "10111"
我們最少需要 3 次翻轉操作來形成 target。
範例 2:
輸入: target = "101"
輸出: 3
解釋: Initially, s = "000".
選擇索引值 i = 0:"000" -> "111"
選擇索引值 i = 1:"111" -> "100"
選擇索引值 i = 2:"100" -> "101"
我們最少需要 3 次翻轉操作來形成 target。
範例 3:
輸入: target = "00000"
輸出: 0
解釋: 我們不需要任何操作,因為一開始的 s 就已經等於 target 了。
解題思維:
可以看到在 s[1] 開始掃過一次 s 的過程中(s[0] 等下再特別判斷),如果遇到 target[i] != target[i - 1],則代表著我們需要改變 s[i] 的狀態。因此操作數會加上 1。
為何只需要看 target 的狀態?因為每次我們修改 s[i],其後的 s[i + 1] 、 s[i + 2] 、 …… 都會與 s[i] 相同。而一旦我們讓 s[i] 與 target[i] 相配,然後再之後遇到第一次的 target[j] != target[j - 1](i < j),則代表著 target[i] ~ target[j - 1] 都是一樣的數字。也因此不需要去改動 s[i + 1] ~ s[j - 1]。
最後多判斷一次 target[0] 是不是 0。如果不是,則代表一開始要先對 s[0] 做一次操作,因此總操作數要 + 1;反之,則上述過程的總操作數即為所求。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。