一、题目
给定一个二进制字符串不带前导零(即:以0开头),如果s
最多包含一个连续的1段
,返回true 。否则,返回false。
二、示例
2.1> 示例 1:
【输入】s = "1001"
【输出】false
【解释】由连续若干个 '1' 组成的字段数量为 2,返回 false
2.2> 示例 2:
【输入】s = "110"
【输出】true
提示:
1
<= s.length <=100
- s[i] 为 '
0
' 或 '1
' - s[0] 为 '
1
'
三、解题思路
3.1> 思路1
根据题目描述,首先要找到有连续1组成的“1段”,那么我们创建一个布尔类型的segmentStarted
,默认值为false,用来表示是否开启了新的“1段”。判断方式就是:
- 如果遍历的字符是“1”,且
segmentStarted
等于false,则将其赋值为true;并且“1段”个数加1;- 如果遍历的字符是“0”,且
segmentStarted
等于true,则将其赋值为false;
当“1段”个数大于1的时候,就返回false;否则返回true;具体如下图所示:
思路1的代码实现,请参见下面的 代码实现:4.1> 实现1中的代码部分。
3.2> 思路2
在上面的解题思路中,我们采用了一个布尔类型的segmentStarted
来判断是否开启了新的“1段”,其实我们可以不使用它,而采用嵌套循环字符“1”的方式。如下图所示,s=“1100110
”,当我们从头遍历的时候,遍历到的字符是“1”,则在遍历的for循环内部,再开启一个while循环,用来遍历后面还是字符‘1’的情况。只有当发现向后遍历的字符是‘0’
或者遍历到数组末尾
了,则跳出while循环(在跳出while循环之前,“1段”个数加1)。而外层的for循环和while循环共用一个遍历的指针i,避免while遍历过的字符,外层for循环再次重复遍历的情况发生。具体如下图所示:
思路2的代码实现,请参见下面的 代码实现:4.2> 实现2 中的代码部分。
3.3> 思路3
在题目描述中,有这样一句话“给你一个二进制字符串 s ,该字符串不含前导零
”,并且在【提示】部分中给出了一个条件“s[0] 为 '1'
”,那么整个s字符串的第一个字符肯定是‘1’,所以,s字符串无论是什么内容,最初的“1段”个数就已经是1了。那么,后续如果我们再发现一个子串为“01
”,那么就直接返回false
即可。不需要其他操作了。具体如下图所示:
思路3的代码实现,请参见下面的 代码实现:4.3> 实现3 中的代码部分。
四、代码实现
4.1> 实现1
class Solution {
public boolean checkOnesSegment(String s) {
char[] sc = s.toCharArray();
int segmentNums = 0;
boolean segmentStartd = false;
for (char item : sc) {
if (item == '1' && !segmentStartd) {
segmentNums++;
segmentStartd = true;
}
if (item == '0' && segmentStartd) segmentStartd = false;
if (segmentNums > 1) return false;
}
return true;
}
}
4.2> 实现2
class Solution {
public boolean checkOnesSegment(String s) {
char[] sc = s.toCharArray();
int segmentNums = 0;
for (int i = 0; i < sc.length; i++) {
if (sc[i] == '1') {
segmentNums++;
while(++i < sc.length) if (sc[i] == '0') break;
}
if (segmentNums > 1) return false;
}
return true;
}
}
4.3> 实现3
class Solution {
public boolean checkOnesSegment(String s) {
return !s.contains("01");
}
}
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」