📫 个人主页:深夜coding算法
📣 专栏系列:2026年华为最新OD机试题库详解
🔥 一次订阅,永久解锁 | 持续更新100+篇 | 6语言全覆盖
文章目录
- ❄️前言:
- ☀️一:题目描述
- 🌙 题目名称
- 🌙 题目内容
- 🌙 输入描述
- 🌙 输出描述
- 🌙 示例
- ☀️二:解题思路
- ☀️三:代码实现
- C++
- Java
- Python3
- C语言
- JavaScript
- Go
- ☀️四:复杂度分析
- ⭐ 五:易错点
- 坑1:翻转次数恰好等于K时也算合法
- 坑2:K可能比字符串还长
- 🌻共勉:
❄️前言:
五子棋迷这题,考的就是滑动窗口 + 边界处理。核心就一句:给定一个最大翻转次数,求最长连续子串。用双指针维护窗口,比暴力枚举快得多。
☀️一:题目描述
🌙 题目名称
五子棋迷
🌙 题目内容
张兵和王武是五子棋迷。工作之余经常切磋棋艺,走棋总有个水平高低,现在约定采用五局三胜制来判断水平高低。
给出对弈的总局数以及每局的胜负情况(1 表示张兵胜,0 表示王武胜),请帮助统计张兵最多能连胜多少局。
注意:可以翻转(改动)至多K局的比赛结果,让张兵(数字1)形成更长的连胜。
🌙 输入描述
第一行:整数K,表示最大翻转次数
第二行:由0和1组成的字符串,1表示张兵胜,0表示王武胜
🌙 输出描述
输出一个整数,表示翻转至多 K 局后,张兵(1)能获得的最长连胜局数。
🌙 示例
输入: 2 10101 输出: 5说明:翻转中间两个0→1,得到11111,最长连胜 5。
☀️二:解题思路
滑动窗口:维护窗口[left, right],窗口内的0个数(需翻转的局数)≤ K。当0的个数 > K 时,收缩左边界。过程中记录窗口最大长度。
☀️三:代码实现
C++
#include<iostream>#include<string>#include<algorithm>usingnamespacestd;intmain(){intK;string s;cin>>K>>s;intn=s.size(),zeros=0,ans=0;for(intL=0,R=0;R<n;R++){if(s[R]=='0')zeros++;while(zeros>K)if(s[L++]=='0')zeros--;ans=max(ans,R-L+1);}cout<<ans<<endl;}Java
importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intK=sc.nextInt();sc.nextLine();Strings=sc.nextLine();intzeros=0,ans=0;for(intL=0,R=0;R<s.length();R++){if(s.charAt(R)=='0')zeros++;while(zeros>K)if(s.charAt(L++)=='0')zeros--;ans=Math.max(ans,R-L+1);}System.out.println(ans);}}Python3
K=int(input())s=input().strip()zeros=ans=L=0forRinrange(len(s)):ifs[R]=='0':zeros+=1whilezeros>K:ifs[L]=='0':zeros-=1L+=1ans=max(ans,R-L+1)print(ans)C语言
#include<stdio.h>#include<string.h>#defineMAX(a,b)((a)>(b)?(a):(b))intmain(){intK,zeros=0,ans=0;chars[1024];scanf("%d\n%s",&K,s);intn=strlen(s);for(intL=0,R=0;R<n;R++){if(s[R]=='0')zeros++;while(zeros>K)if(s[L++]=='0')zeros--;ans=MAX(ans,R-L+1);}printf("%d\n",ans);}JavaScript
constinput=require('fs').readFileSync(0,'utf-8').trim().split('\n');constK=+input[0],s=input[1];letzeros=0,ans=0,L=0;for(letR=0;R<s.length;R++){if(s[R]==='0')zeros++;while(zeros>K)if(s[L++]==='0')zeros--;ans=Math.max(ans,R-L+1);}console.log(ans);Go
packagemainimport("fmt")funcmain(){varKint;varsstringfmt.Scanf("%d\n%s",&K,&s)zeros,ans,L:=0,0,0forR:=0;R<len(s);R++{ifs[R]=='0'{zeros++}forzeros>K{ifs[L]=='0'{zeros--}L++}ifR-L+1>ans{ans=R-L+1}}fmt.Println(ans)}☀️四:复杂度分析
| 指标 | 数值 |
|---|---|
| 时间复杂度 | O(N) |
| 空间复杂度 | O(1) |
⭐ 五:易错点
坑1:翻转次数恰好等于K时也算合法
zeros <= K是条件,不能写成< K。
坑2:K可能比字符串还长
如果 K ≥ 字符串长度,答案就是字符串长度本身。
🌻共勉:
滑动窗口三板斧:扩右边界、收左边界、更新答案。这题练的就是这个节奏。
📫关于本专栏:一次订阅,永久解锁全部100+篇真题详解
🔥6语言全覆盖:Java | Python3 | C++ | C语言 | JsNode | Go