
2026-01-30:使二进制字符串全为 1 的最少操作次数。用go语言,给你一个只含 0 和 1 的字符串 s,以及一个整数 k。
一次操作中必须从不同的位置中选出恰好 k 个索引,并把这些位置上的字符取反(0 变为 1,1 变为 0)。要求通过若干次这样的操作,把字符串变为全部为 1。
输出使字符串全部变为 1 所需的最少操作次数;如果无论如何都办不到,则返回 -1。
1 <= s.length <= 100000。
s[i] 的值为 '0' 或 '1'。
1 <= k <= s.length。
输入: s = "0101", k = 3。
输出: 2。
解释:
每次操作选择 k = 3 个下标的一种最优操作方案是:
操作 1:翻转下标 [0, 1, 3]。s 从 "0101" 变为 "1000"。
操作 2:翻转下标 [1, 2, 3]。s 从 "1000" 变为 "1111"。
因此,最少操作次数为 2。
题目来自力扣3666。
s 的长度 n,并统计其中 '0' 的个数 z。例如,对于 s = "0101",n = 4,z = 2。z == 0,说明字符串已经全为 '1',无需任何操作,直接返回 0。k == n(即一次操作必须翻转所有字符):z == n(字符串全为 '0'),则只需一次操作即可将其变为全 '1',返回 1。'0' 也有 '1'),一次翻转后 '0' 会变成 '1',但原来的 '1' 会变成 '0',无法达到全 '1',因此返回 -1。核心思想是,每次操作翻转 k 个位置,相当于改变了 z('0' 的数量)的值。每次操作后,z 的变化量是 k - 2 * (被翻转位置中原本是 '0' 的数量)。为了最小化操作次数,需要找到一种操作序列,使得 z 最终变为 0。
代码通过分析操作次数的奇偶性与初始 z 和 k 的奇偶性关系,来推导最小操作次数 m。它考虑了两种情况:
m 为偶数'0' 的个数 z 必须是偶数(z % 2 == 0)。m1 = max((z + k - 1) / k, (z + n - k - 1) / (n - k)) 计算一个理论上的最小操作次数下界。这个公式考虑了最有效的翻转方式。m 为偶数,因此将 m1 向上调整为最接近的偶数,作为该情况的候选答案。m 为奇数'0' 的个数 z 和每次翻转的个数 k 必须具有相同的奇偶性(z % 2 == k % 2)。m2 = max((z + k - 1) / k, (n - z + n - k - 1) / (n - k)) 来计算下界。m2 向上调整为最接近的奇数,作为此情况的候选答案。ans 仍为初始的最大整数值),说明无法通过操作将字符串变为全 '1',返回 -1。strings.Count 函数遍历字符串来统计 '0' 的个数 z。后续的计算步骤只涉及常数时间的数学运算。n, z, k, ans, m 等),没有使用与输入规模 n 相关的额外空间。这个算法巧妙地利用了奇偶性这一数学性质,避免了复杂的模拟过程,将问题转化为在特定约束条件下寻找满足奇偶性的最小操作数,从而实现了高效的求解。
.
package main
import (
"fmt"
"math"
"strings"
)
func minOperations(s string, k int)int {
n := len(s)
z := strings.Count(s, "0")
if z == 0 {
return0
}
if k == n {
if z == n {
return1
}
return-1
}
ans := math.MaxInt
// 情况一:操作次数 m 是偶数
if z%2 == 0 { // z 必须是偶数
m := max((z+k-1)/k, (z+n-k-1)/(n-k)) // 下界
ans = m + m%2 // 把 m 往上调整为偶数
}
// 情况二:操作次数 m 是奇数
if z%2 == k%2 { // z 和 k 的奇偶性必须相同
m := max((z+k-1)/k, (n-z+n-k-1)/(n-k)) // 下界
ans = min(ans, m|1) // 把 m 往上调整为奇数
}
if ans < math.MaxInt {
return ans
}
return-1
}
func main() {
s := "0101"
k := 3
result := minOperations(s, k)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
import math
def minOperations(s: str, k: int) -> int:
n = len(s)
z = s.count('0')
if z == 0:
return0
if k == n:
if z == n:
return1
return-1
ans = math.inf
# 情况一:操作次数 m 是偶数
if z % 2 == 0: # z 必须是偶数
m = max((z + k - 1) // k, (z + n - k - 1) // (n - k)) # 下界
ans = m + (m % 2) # 把 m 往上调整为偶数
# 情况二:操作次数 m 是奇数
if z % 2 == k % 2: # z 和 k 的奇偶性必须相同
m = max((z + k - 1) // k, (n - z + n - k - 1) // (n - k)) # 下界
ans = min(ans, m if m % 2 == 1else m + 1) # 把 m 往上调整为奇数
return ans if ans < math.inf else-1
if __name__ == "__main__":
s = "0101"
k = 3
result = minOperations(s, k)
print(result)
.
#include <iostream>
#include <string>
#include <algorithm>
#include <climits>
using namespace std;
int minOperations(string s, int k) {
int n = s.length();
int z = count(s.begin(), s.end(), '0');
if (z == 0) {
return0;
}
if (k == n) {
if (z == n) {
return1;
}
return-1;
}
int ans = INT_MAX;
// 情况一:操作次数 m 是偶数
if (z % 2 == 0) { // z 必须是偶数
int m = max((z + k - 1) / k, (z + n - k - 1) / (n - k)); // 下界
ans = m + (m % 2); // 把 m 往上调整为偶数
}
// 情况二:操作次数 m 是奇数
if (z % 2 == k % 2) { // z 和 k 的奇偶性必须相同
int m = max((z + k - 1) / k, (n - z + n - k - 1) / (n - k)); // 下界
ans = min(ans, m | 1); // 把 m 往上调整为奇数
}
return ans < INT_MAX ? ans : -1;
}
int main() {
string s = "0101";
int k = 3;
int result = minOperations(s, k);
cout << result << endl;
return0;
}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。