Facebook Pixel

1784. Check if Binary String Has at Most One Segment of Ones

EasyString
Leetcode Link

Problem Description

You are given a binary string s that contains only '0's and '1's and has no leading zeros (meaning it doesn't start with '0').

Your task is to determine if the string contains at most one contiguous segment of ones. A contiguous segment of ones means consecutive '1's that appear together without any '0's in between.

Return true if there is at most one such segment, and false otherwise.

For example:

  • "1110000" has exactly one segment of ones at the beginning → return true
  • "110111" has two segments of ones (one at the beginning "11" and another "111" after the '0') → return false
  • "1" has exactly one segment → return true
  • "111" has exactly one segment → return true

The key insight is that since the string has no leading zeros, it must start with '1'. If we ever encounter the pattern "01" in the string, it means there's a '1' appearing after a '0', which indicates a second segment of ones has started. Therefore, checking whether "01" exists in the string is sufficient to solve this problem.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Since the string has no leading zeros, we know it must start with '1'. This is a crucial observation.

Let's think about what happens when we have multiple segments of ones. If we have more than one segment, the string would look something like: "111...000...111...". To go from the first segment of ones to the second segment, we must:

  1. First encounter a '0' (ending the first segment)
  2. Then encounter a '1' (starting the second segment)

This creates the pattern "01" somewhere in the string.

On the other hand, if we have at most one segment of ones, the string can only be in one of these forms:

  • Just ones: "1111..."
  • Ones followed by zeros: "1111...0000..."

In both these valid cases, we never have a '1' coming after a '0', so the pattern "01" never appears.

The beauty of this observation is that we don't need to count segments or track state as we traverse the string. We can simply check if the substring "01" exists anywhere in the string. If it does, we have more than one segment (return false). If it doesn't, we have at most one segment (return true).

This reduces a seemingly complex problem of counting contiguous segments to a simple substring search, making the solution elegant and efficient with just one line: return '01' not in s.

Solution Approach

The implementation is remarkably simple based on our observation that multiple segments of ones will always create the pattern "01" in the string.

Algorithm Steps:

  1. Check if the substring "01" exists in the given string s
  2. If "01" is found, return false (more than one segment exists)
  3. If "01" is not found, return true (at most one segment exists)

Implementation Details:

The Python solution uses the in operator for substring checking:

return '01' not in s

This one-liner works because:

  • Python's in operator efficiently searches for the substring "01" within s
  • The expression '01' not in s evaluates to True when "01" is absent (valid case with at most one segment)
  • It evaluates to False when "01" is present (invalid case with multiple segments)

Why This Works:

Since s doesn't have leading zeros, it must start with '1'. The only way to have multiple segments of ones is to have the pattern:

  • "1...1" (first segment)
  • followed by "0...0" (gap between segments)
  • followed by "1...1" (second segment)

This transition from zeros back to ones creates the "01" pattern. Therefore:

  • Strings like "1110000" are valid (no "01" pattern)
  • Strings like "1101" or "110111" are invalid (contain "01" pattern)

Time Complexity: O(n) where n is the length of the string, as substring search requires scanning the string.

Space Complexity: O(1) as we only use constant extra space for the substring pattern check.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution approach with a concrete example: s = "1100111"

Step 1: Identify what we're looking for We need to check if there's at most one contiguous segment of ones. Since the string has no leading zeros, it must start with '1'.

Step 2: Apply our key observation We look for the pattern "01" in the string. Let's scan through "1100111":

  • Position 0-1: "11" - no match
  • Position 1-2: "10" - no match
  • Position 2-3: "00" - no match
  • Position 3-4: "01" - MATCH FOUND!

Step 3: Interpret the result Since we found "01" at position 3-4, this indicates a '1' appears after a '0'. This means:

  • The first segment of ones: "11" (positions 0-1)
  • Then zeros: "00" (positions 2-3)
  • Then another segment of ones: "111" (positions 4-6)

We have two segments of ones, so the answer is false.

Verification: Let's verify with a valid example: s = "1110000"

  • Scanning for "01": No matter where we look, we only see patterns like "11", "10", or "00"
  • Since "01" is not found, we have at most one segment
  • Indeed, there's only one segment of ones at the beginning: "111"
  • The answer is true

Code execution:

# For s = "1100111"
return '01' not in s  # '01' is in "1100111", so returns False

# For s = "1110000"  
return '01' not in s  # '01' is not in "1110000", so returns True

Solution Implementation

1class Solution:
2    def checkOnesSegment(self, s: str) -> bool:
3        """
4        Check if all '1's in the binary string form exactly one contiguous segment.
5      
6        The logic: If the pattern '01' exists in the string, it means there's a '0' 
7        followed by a '1', indicating that '1's appear again after being interrupted 
8        by '0's, which means multiple segments exist.
9      
10        Args:
11            s: A binary string containing only '0's and '1's
12          
13        Returns:
14            True if all '1's form a single contiguous segment, False otherwise
15        """
16        # Check if the substring '01' exists in the string
17        # If '01' is not found, all '1's are contiguous (return True)
18        # If '01' is found, there are multiple segments of '1's (return False)
19        return '01' not in s
20
1class Solution {
2    /**
3     * Checks if all '1's in the binary string form a single contiguous segment.
4     * 
5     * The logic: If there are multiple segments of '1's, there must be at least
6     * one occurrence of "01" pattern (transitioning from '0' back to '1').
7     * A single segment means we never go from '0' to '1' after the initial segment.
8     * 
9     * @param s - A binary string containing only '0's and '1's
10     * @return true if all '1's form a single contiguous segment, false otherwise
11     */
12    public boolean checkOnesSegment(String s) {
13        // Check if the string does NOT contain the pattern "01"
14        // If "01" is absent, all '1's must be in a single contiguous segment
15        return !s.contains("01");
16    }
17}
18
1class Solution {
2public:
3    /**
4     * Check if all '1's in the binary string form a single contiguous segment.
5     * 
6     * The string contains a single segment of '1's if there are no '0's followed by '1's.
7     * If pattern "01" exists, it means '1's are split into multiple segments.
8     * 
9     * @param s - Binary string containing only '0's and '1's
10     * @return true if all '1's form a single contiguous segment, false otherwise
11     */
12    bool checkOnesSegment(string s) {
13        // Check if pattern "01" exists in the string
14        // If "01" is not found (returns string::npos), all '1's are contiguous
15        return s.find("01") == string::npos;
16    }
17};
18
1/**
2 * Checks if all '1's in the binary string form a single contiguous segment.
3 * A contiguous segment means all '1's appear together without any '0's in between.
4 * 
5 * @param s - A binary string containing only '0's and '1's
6 * @returns true if all '1's form a single contiguous segment, false otherwise
7 */
8function checkOnesSegment(s: string): boolean {
9    // Store the previous character for comparison
10    let previousChar: string = s[0];
11  
12    // Iterate through each character in the string
13    for (const currentChar of s) {
14        // If we transition from '0' to '1', it means we found a second segment of '1's
15        // This violates the single segment requirement
16        if (previousChar !== currentChar && currentChar === '1') {
17            return false;
18        }
19      
20        // Update the previous character for the next iteration
21        previousChar = currentChar;
22    }
23  
24    // If we complete the loop without finding multiple segments, return true
25    return true;
26}
27

Time and Space Complexity

The time complexity is O(n), where n is the length of the string s. This is because the in operator in Python needs to traverse through the string to check if the substring '01' exists. In the worst case, it examines all characters in the string.

The space complexity is O(1). The algorithm only uses a constant amount of extra space regardless of the input size. The substring '01' being searched for is a fixed constant, and no additional data structures that scale with input size are created.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

Pitfall 1: Misunderstanding Edge Cases

The Mistake: Developers might overthink edge cases and add unnecessary complexity, such as:

  • Explicitly checking for empty strings
  • Handling strings with only '0's or only '1's separately
  • Adding special logic for single-character strings
# Overcomplicated approach - unnecessary!
def checkOnesSegment(self, s: str) -> bool:
    if not s or len(s) == 1:  # Unnecessary edge case handling
        return True
    if '1' not in s:  # Unnecessary check
        return True
    return '01' not in s

Why It's Wrong: The simple '01' not in s check already handles all these cases correctly:

  • Empty string: '01' not in '' returns True (valid)
  • Single character: '01' not in '1' or '01' not in '0' both return True (valid)
  • All zeros: '01' not in '0000' returns True (valid - zero segments is "at most one")

The Fix: Trust the simplicity of the solution. The one-liner handles all edge cases naturally.

Pitfall 2: Incorrect Pattern Matching

The Mistake: Some might try to check for the wrong pattern or use complex regex:

# Wrong approach - checking for '10' instead
def checkOnesSegment(self, s: str) -> bool:
    return '10' not in s  # This doesn't catch all cases!

Why It's Wrong: Checking for '10' pattern misses cases like "111011". The '10' pattern only indicates the end of a segment of ones, not the start of a new one. The string "1110000" contains '10' but is still valid.

The Fix: Always check for '01' pattern, which specifically indicates a '1' appearing after a '0', marking the start of a new segment.

Pitfall 3: Manual Iteration with State Tracking

The Mistake: Implementing complex state machines or flag-based solutions:

# Overly complex manual approach
def checkOnesSegment(self, s: str) -> bool:
    seen_zero = False
    for i in range(len(s)):
        if s[i] == '0':
            seen_zero = True
        elif s[i] == '1' and seen_zero:
            return False  # Found a '1' after seeing a '0'
    return True

Why It's Problematic: While this works, it's:

  • More code to write and maintain
  • Higher chance of bugs (off-by-one errors, incorrect flag handling)
  • Less readable than the simple substring check
  • Potentially slower due to Python loop overhead

The Fix: Use Python's built-in substring search which is optimized at the C level and more concise:

return '01' not in s
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which type of traversal does breadth first search do?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More