Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

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

Problem Description

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:

  • The input string s consists only of '0' and '1' characters.
  • The length of s is at least 1.
Examples:
  • 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)

Thought Process

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.

Solution Approach

Let's break down the optimized solution step by step:

  1. Scan the string from left to right.
    • Keep track of whether we are currently in a segment of '1's.
    • When we see a '1' after a '0' (and we've already seen a segment of '1's), we know there must be a second segment.
  2. Alternative (simpler): Since the problem is about non-contiguous '1's, we can check if the string contains the substring '01' followed by a '1' again. But the easiest way is to check if the string contains the substring '01' and then '10'. However, even more simply, if the string contains the substring '01', and there is a '1' after that, we have more than one segment.
  3. Most concise approach: Check if the string contains the substring '01'. If it does, check if there is a '1' after that. But since the segments are contiguous, if there is more than one segment, there must be a '0' between two '1's. Therefore, if the string contains '01', and then '1' again, return false.
  4. Even simpler: Actually, if the string contains the substring '01', and then '1' again, it's equivalent to the string containing the substring '10' and then '1'. But the simplest way is: if the string contains the substring '01', and then '1' again, return false. Otherwise, return true.
  5. Most practical approach: The problem boils down to: if the string contains the substring '01', and then '1' again, return 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.

  • Python/Java/JavaScript: Use the built-in 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.
  • C++: Use the 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.

Example Walkthrough

Let's use s = "1001" as an example:

  • We start at index 0: '1' (beginning of a segment of '1's)
  • Index 1: '0' (end of the first segment of '1's)
  • Index 2: '0' (still in '0's)
  • Index 3: '1' (start of a new segment of '1's) → Second segment detected!
  • Thus, we return false.

Another example: s = "110"

  • Index 0: '1' (start of segment)
  • Index 1: '1' (still in segment)
  • Index 2: '0' (end of segment)
  • No more '1's after the first group → Only one segment
  • Return true.

Code Implementation

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");
};
      

Time and Space Complexity

Brute-force Approach:

  • Scan through the string and count the number of distinct segments of '1's.
  • Time Complexity: O(n), where n is the length of the string (since we scan each character once).
  • Space Complexity: O(1), as we only need a few counters or flags.
Optimized Approach (as above):
  • We check if '01' exists in the string, which is also O(n) time (since substring search is linear).
  • Space Complexity: O(1), since no extra space is used beyond a constant amount.

Both approaches are efficient, but the substring search is more concise and avoids explicit loops.

Summary

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.