# LeetCode 434: Number of Segments in a String

## Problem Restatement

We are given a string `s`.

A segment is a contiguous sequence of non-space characters.

We need to count how many segments appear in the string.

For example:

```python
s = "Hello, my name is John"
```

contains these segments:

```text
"Hello,"
"my"
"name"
"is"
"John"
```

So the answer is:

```python
5
```

The official problem defines a segment as a contiguous sequence of non-space characters. The string may contain leading spaces, trailing spaces, or multiple spaces between words. ([leetcode.com](https://leetcode.com/problems/number-of-segments-in-a-string/?utm_source=chatgpt.com))

## Input and Output

| Item | Meaning |
|---|---|
| Input | String `s` |
| Output | Number of segments |
| Segment | Consecutive non-space characters |
| Spaces | May appear anywhere |

Example function shape:

```python
def countSegments(s: str) -> int:
    ...
```

## Examples

Example 1:

```python
s = "Hello, my name is John"
```

Segments:

```text
Hello,
my
name
is
John
```

Answer:

```python
5
```

Example 2:

```python
s = "Hello"
```

There is only one segment:

```python
1
```

Example 3:

```python
s = "   Hello   world   "
```

The extra spaces do not create empty segments.

Only these count:

```text
Hello
world
```

Answer:

```python
2
```

Example 4:

```python
s = ""
```

No segments exist.

Answer:

```python
0
```

## First Thought: Split the String

A direct idea is:

```python
s.split()
```

Python automatically removes repeated spaces.

For example:

```python
"   Hello   world   ".split()
```

becomes:

```python
["Hello", "world"]
```

So we could simply return:

```python
len(s.split())
```

This works.

However, the problem becomes more interesting if we solve it manually using character scanning.

## Key Insight

A new segment starts when:

1. The current character is not a space.
2. Either:
   - it is the first character, or
   - the previous character is a space.

So we only need to count transitions like:

```text
space -> non-space
```

For example:

```text
"   Hello   world"
     ^
```

The `H` starts a new segment because it follows a space.

Later:

```text
"   Hello   world"
             ^
```

The `w` also starts a new segment.

This lets us solve the problem in one pass.

## Algorithm

Initialize:

```python
count = 0
```

Scan the string from left to right.

For each character `s[i]`:

If:

```python
s[i] != ' '
```

and:

```python
i == 0 or s[i - 1] == ' '
```

then we found the start of a new segment.

Increase:

```python
count += 1
```

After scanning the whole string, return `count`.

## Correctness

A segment is defined as a maximal contiguous sequence of non-space characters.

Every segment has exactly one starting position:

| Condition | Meaning |
|---|---|
| current character is non-space | we are inside a segment |
| previous character is space or does not exist | this is the first character of the segment |

The algorithm counts exactly these positions.

Suppose a segment starts at index `i`.

Then:

```python
s[i] != ' '
```

and either:

```python
i == 0
```

or:

```python
s[i - 1] == ' '
```

So the algorithm increases the count once for that segment.

Now consider any counted position.

The algorithm only counts when a non-space character begins after a space or at the beginning of the string. Therefore, the counted position must be the first character of a segment.

Since every segment is counted exactly once and no non-segment positions are counted, the returned value equals the number of segments.

## Complexity

| Metric | Value | Why |
|---|---:|---|
| Time | `O(n)` | We scan the string once |
| Space | `O(1)` | Only a counter is used |

Here, `n` is the length of the string.

## Implementation

```python
class Solution:
    def countSegments(self, s: str) -> int:
        count = 0

        for i in range(len(s)):
            if s[i] != ' ' and (i == 0 or s[i - 1] == ' '):
                count += 1

        return count
```

## Code Explanation

We begin with:

```python
count = 0
```

This stores the number of detected segments.

We scan every character:

```python
for i in range(len(s)):
```

The first condition:

```python
s[i] != ' '
```

ensures the current character belongs to a segment.

The second condition:

```python
i == 0 or s[i - 1] == ' '
```

checks whether this character begins a new segment.

If both conditions hold, we increment the answer:

```python
count += 1
```

Finally, we return the total number of segment starts.

## Testing

```python
def run_tests():
    s = Solution()

    assert s.countSegments("Hello, my name is John") == 5

    assert s.countSegments("Hello") == 1

    assert s.countSegments("   Hello   world   ") == 2

    assert s.countSegments("") == 0

    assert s.countSegments("      ") == 0

    assert s.countSegments("a b c") == 3

    assert s.countSegments("   a") == 1

    assert s.countSegments("a   ") == 1

    print("all tests passed")

run_tests()
```

Test meaning:

| Test | Why |
|---|---|
| Normal sentence | Checks ordinary word counting |
| Single word | Checks smallest non-empty segment |
| Leading and trailing spaces | Checks ignored spaces |
| Empty string | Checks zero segments |
| Only spaces | Confirms spaces alone do not form segments |
| Multiple small words | Checks repeated transitions |
| Leading spaces before word | Checks segment start detection |
| Trailing spaces after word | Checks segment end handling |

