📫 个人主页:深夜coding算法
📣 专栏系列:2026年华为最新OD机试题库详解
🔥 一次订阅,永久解锁 | 持续更新100+篇 | 6语言全覆盖
文章目录
- ❄️前言:
- ☀️一:题目描述
- 🌙 题目名称
- 🌙 题目内容
- 🌙 输入描述
- 🌙 输出描述
- 🌙 示例1
- 🌙 示例2
- 🌙 示例3
- ☀️二:题目解析
- ☀️三:解题思路
- ☀️四:代码实现
- C++
- Java
- Python3
- C语言
- JavaScript
- Go
- ☀️五:复杂度分析
- ⭐ 六:易错点
- 坑1:检查范围越界
- 坑2:边坐边更新
- 🌻共勉:
❄️前言:
这道题猛一看像是"左右观察"的复杂逻辑,但捋清楚之后就是一层循环搞定——每个空位能不能坐,取决于左边的人和右边的人。一次遍历,判断放座。
☀️一:题目描述
🌙 题目名称
座位调整
🌙 题目内容
疫情期间课堂里需要间隔就坐。用一个由0和1组成的字符串表示座位情况,其中0表示座位是空的,1表示座位已被占用。
要求对空座位进行调整,使得任意两个占用座位之间至少隔两个空座位(即占用的座位之间最少间隔两个座位),计算最多还能安排几人就坐。
🌙 输入描述
输入一行字符串,由0和1组成,表示当前座位占用情况。
🌙 输出描述
输出一个整数,表示最多还能安排几人就坐。
🌙 示例1
输入: 01001 输出: 1说明:在位置01001中,第一个0(索引0)与已有1相邻不能坐,最后一个0(索引4)可以插入一人。结果:01011,因此答案是 1。
🌙 示例2
输入: 000 输出: 1说明:三个连续空位,在中间位置(索引1)坐一人即可满足条件。
🌙 示例3
输入: 101 输出: 0说明:所有空位都被左右1夹着,无法安排新人。
☀️二:题目解析
| 要点 | 解读 |
|---|---|
| 间隔至少2个空位 | 占用座位之间至少隔两个0 |
| 最多安排人数 | 贪心:从左扫到右,能坐就坐 |
| 0 和 1 的字符串 | 输入是纯字符串,只包含字符0和1 |
☀️三:解题思路
贪心遍历:对于每个位置 i,同时检查左边和右边的两个位置是否都为空。如果是,则占座并计数。
遍历每个位置 i: (1)当前位置是空位(arr[i]=='0') (2)左边两个位置没有占用(i<1 或 arr[i-1]!='1'、i<2 或 arr[i-2]!='1') (3)右边两个位置没有占用(i+1>=n 或 arr[i+1]!='1'、i+2>=n 或 arr[i+2]!='1') 满足三个条件 → 坐下(arr[i]='1'),计数+1☀️四:代码实现
C++
#include<iostream>#include<string>usingnamespacestd;intmain(){string s;cin>>s;intn=s.size(),cnt=0;for(inti=0;i<n;i++){if(s[i]=='1')continue;// 已占用,跳过boolleftOk=(i<1||s[i-1]!='1')&&(i<2||s[i-2]!='1');boolrightOk=(i+1>=n||s[i+1]!='1')&&(i+2>=n||s[i+2]!='1');if(leftOk&&rightOk){s[i]='1';// 占座cnt++;}}cout<<cnt<<endl;return0;}Java
importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);char[]s=sc.nextLine().toCharArray();intn=s.length,cnt=0;for(inti=0;i<n;i++){if(s[i]=='1')continue;booleanleftOk=(i<1||s[i-1]!='1')&&(i<2||s[i-2]!='1');booleanrightOk=(i+1>=n||s[i+1]!='1')&&(i+2>=n||s[i+2]!='1');if(leftOk&&rightOk){s[i]='1';cnt++;}}System.out.println(cnt);}}Python3
s=list(input().strip())n=len(s)cnt=0foriinrange(n):ifs[i]=='1':continueleft_ok=(i<1ors[i-1]!='1')and(i<2ors[i-2]!='1')right_ok=(i+1>=nors[i+1]!='1')and(i+2>=nors[i+2]!='1')ifleft_okandright_ok:s[i]='1'cnt+=1print(cnt)C语言
#include<stdio.h>#include<string.h>intmain(){chars[1024];scanf("%s",s);intn=strlen(s),cnt=0;for(inti=0;i<n;i++){if(s[i]=='1')continue;intleftOk=(i<1||s[i-1]!='1')&&(i<2||s[i-2]!='1');intrightOk=(i+1>=n||s[i+1]!='1')&&(i+2>=n||s[i+2]!='1');if(leftOk&&rightOk){s[i]='1';cnt++;}}printf("%d\n",cnt);return0;}JavaScript
constreadline=require('readline');constrl=readline.createInterface({input:process.stdin,output:process.stdout});rl.on('line',(line)=>{consts=[...line.trim()];constn=s.length;letcnt=0;for(leti=0;i<n;i++){if(s[i]==='1')continue;constleftOk=(i<1||s[i-1]!=='1')&&(i<2||s[i-2]!=='1');constrightOk=(i+1>=n||s[i+1]!=='1')&&(i+2>=n||s[i+2]!=='1');if(leftOk&&rightOk){s[i]='1';cnt++;}}console.log(cnt);rl.close();});Go
packagemainimport"fmt"funcmain(){varsstringfmt.Scan(&s)b:=[]byte(s)n,cnt:=len(b),0fori:=0;i<n;i++{ifb[i]=='1'{continue}leftOk:=(i<1||b[i-1]!='1')&&(i<2||b[i-2]!='1')rightOk:=(i+1>=n||b[i+1]!='1')&&(i+2>=n||b[i+2]!='1')ifleftOk&&rightOk{b[i]='1'cnt++}}fmt.Println(cnt)}☀️五:复杂度分析
| 指标 | 数值 |
|---|---|
| 时间复杂度 | O(N) |
| 空间复杂度 | O(N) |
⭐ 六:易错点
坑1:检查范围越界
检查左右邻居时注意数组边界,用i<1、i+1>=n等条件兜底。
坑2:边坐边更新
每坐一个人就要把当前位置标记为1,否则后面的人统计时不会把它当成已占用。
🌻共勉:
贪心题的核心就一句话:能坐就坐,别犹豫。想多了反而把自己绕进去。
📫关于本专栏:一次订阅,永久解锁全部100+篇真题详解
🔥6语言全覆盖:Java | Python3 | C++ | C语言 | JsNode | Go
以上就是本篇博客的所有内容,觉得有帮助的话,记得点赞收藏关注走一波~~🥝