Given a binary string s
(a string consisting only of the characters '0' and '1'), determine if the string contains at most one contiguous segment of '1's. In other words, all the '1's in the string must appear together in a single block, and there cannot be two or more separated groups of '1's.
Constraints:
s
consists only of '0' and '1' characters.s
is at least 1.s = "110"
→ true
(one segment of '1's)s = "1001"
→ false
(two segments of '1's)s = "000"
→ true
(zero segments of '1's)s = "1"
→ true
(one segment of '1's)
To solve this problem, we need to determine if all the '1's in the string are grouped together. If there are two or more groups of '1's separated by at least one '0', the answer is false
.
The brute-force approach would be to scan through the string and count how many separate segments of '1's exist. But we can optimize this by observing that if there is a '0' followed by a '1' after the first segment of '1's, then there is more than one segment.
In other words, we can look for the pattern '01' followed by '1', or more simply, check if the string contains the substring '01' and then another '1' after that. But even simpler, we can check if the string contains the substring '01' more than once, or if it contains '10' and then '1' again.
Alternatively, we can use string operations or a simple scan to detect the transition from '1' to '0' and then back to '1' again, which would indicate more than one segment.
Let's break down the optimized solution step by step:
false
.
false
. Otherwise, return true
.
false
. Otherwise, return true
.
In summary, the easiest way is to check if the string contains the substring '01' more than once, or if the string contains the substring '10' and then '1' again. But the simplest way is to check if the string contains the substring '01' and then '1' again.
in
operator or contains()
method to check for the substring '01'. If '01' is present, and there is a '1' after that, return false
. Otherwise, return true
.
find()
method to check for the substring '01'. If '01' is present, and there is a '1' after that, return false
. Otherwise, return true
.
Alternatively, a simple scan through the string, keeping track of when we move from '1' to '0' and then see a '1' again, suffices.
Let's use s = "1001"
as an example:
false
.
Another example: s = "110"
true
.class Solution:
def checkOnesSegment(self, s: str) -> bool:
# Once we see a '0', there should not be any '1' after it
return '01' not in s
class Solution {
public:
bool checkOnesSegment(string s) {
// If "01" exists, there is more than one segment
return s.find("01") == string::npos;
}
};
class Solution {
public boolean checkOnesSegment(String s) {
// If "01" exists, there is more than one segment
return !s.contains("01");
}
}
var checkOnesSegment = function(s) {
// If "01" exists, there is more than one segment
return !s.includes("01");
};
Brute-force Approach:
Both approaches are efficient, but the substring search is more concise and avoids explicit loops.
This problem demonstrates how recognizing a pattern in the input can lead to a very concise and efficient solution. By noting that multiple segments of '1's must be separated by at least one '0', we can simply check for the presence of the substring '01' to determine if there is more than one segment. This leads to a one-line solution in most languages, making the approach both elegant and optimal.