434. Number of Segments in a String

EasyString
Leetcode Link

Problem Description

The problem provides you with a string s and asks you to find the number of segments in this string. Here, a segment is considered to be a continuous sequence of characters that does not include any spaces. This means that words separated by one or more spaces are counted as distinct segments. The task is to count these segments and return the number.

For example, in the string "Hello, my name is John", there are five segments: "Hello,", "my", "name", "is", "John".

Intuition

The intuition for solving this problem is based on the definition of a segment. Since a segment is defined as a contiguous sequence of non-space characters, we can look for transitions from a space to a non-space character to identify the start of a segment.

The following points form the basis of the intuition:

  • If the current character is not a space, it might be a part of a segment.
  • To confirm if it's the start of a new segment, check the character that comes before it. If the preceding character is a space (or if there is no preceding character, as when the current character is the first in the string), then it's the start of a new segment.
  • Increment the segment count each time we spot the start of a new segment.

The solution iterates through the string, examining each character and its predecessor to count segments according to the rules above. Simple and to the point!

Not Sure What to Study? Take the 2-min Quiz to Find Your Missing Piece:

What's the output of running the following function using input 56?

1KEYBOARD = {
2    '2': 'abc',
3    '3': 'def',
4    '4': 'ghi',
5    '5': 'jkl',
6    '6': 'mno',
7    '7': 'pqrs',
8    '8': 'tuv',
9    '9': 'wxyz',
10}
11
12def letter_combinations_of_phone_number(digits):
13    def dfs(path, res):
14        if len(path) == len(digits):
15            res.append(''.join(path))
16            return
17
18        next_number = digits[len(path)]
19        for letter in KEYBOARD[next_number]:
20            path.append(letter)
21            dfs(path, res)
22            path.pop()
23
24    res = []
25    dfs([], res)
26    return res
27
1private static final Map<Character, char[]> KEYBOARD = Map.of(
2    '2', "abc".toCharArray(),
3    '3', "def".toCharArray(),
4    '4', "ghi".toCharArray(),
5    '5', "jkl".toCharArray(),
6    '6', "mno".toCharArray(),
7    '7', "pqrs".toCharArray(),
8    '8', "tuv".toCharArray(),
9    '9', "wxyz".toCharArray()
10);
11
12public static List<String> letterCombinationsOfPhoneNumber(String digits) {
13    List<String> res = new ArrayList<>();
14    dfs(new StringBuilder(), res, digits.toCharArray());
15    return res;
16}
17
18private static void dfs(StringBuilder path, List<String> res, char[] digits) {
19    if (path.length() == digits.length) {
20        res.add(path.toString());
21        return;
22    }
23    char next_digit = digits[path.length()];
24    for (char letter : KEYBOARD.get(next_digit)) {
25        path.append(letter);
26        dfs(path, res, digits);
27        path.deleteCharAt(path.length() - 1);
28    }
29}
30
1const KEYBOARD = {
2    '2': 'abc',
3    '3': 'def',
4    '4': 'ghi',
5    '5': 'jkl',
6    '6': 'mno',
7    '7': 'pqrs',
8    '8': 'tuv',
9    '9': 'wxyz',
10}
11
12function letter_combinations_of_phone_number(digits) {
13    let res = [];
14    dfs(digits, [], res);
15    return res;
16}
17
18function dfs(digits, path, res) {
19    if (path.length === digits.length) {
20        res.push(path.join(''));
21        return;
22    }
23    let next_number = digits.charAt(path.length);
24    for (let letter of KEYBOARD[next_number]) {
25        path.push(letter);
26        dfs(digits, path, res);
27        path.pop();
28    }
29}
30

Solution Approach

The solution to this problem is implemented in a very straightforward manner, without the use of complex algorithms or data structures. It uses a simple loop and conditionals to evaluate the characters of the string one by one.

Here's a breakdown of the implementation:

  • Initialize a counter variable ans with a value of 0.
  • Loop through the string s using the enumerate function, which gives us both the index i and the character c for each iteration.
  • Inside the loop, check if the current character c is not a space. Since we are only interested in non-space characters, we ignore spaces.
  • Then, check if it's the first character in the string (i == 0) or if the preceding character is a space (s[i - 1] == ' ').
  • If either condition is true, it signifies the start of a new segment, and the counter ans should be incremented by 1.
  • Continue this process until you have examined all the characters in the string.
  • After the loop concludes, return the value of ans as it now contains the total count of segments in the string s.

The algorithm effectively uses a finite state machine pattern where you're only changing the state (incrementing the counter) when certain conditions (state transitions) are met, that is—from space to non-space. It operates in linear time complexity (O(n)), where n is the length of the string s, because it examines each character exactly once.

Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:

Given an array of 1,000,000 integers that is almost sorted, except for 2 pairs of integers. Which algorithm is fastest for sorting the array?

Example Walkthrough

Let's illustrate the solution approach with a small example string s = " Algo Expert ". We want to count the number of segments (i.e., words) in this string. Remember, a segment is defined as a contiguous sequence of non-space characters.

Following the solution approach:

  1. Initialize ans to 0 because we haven't counted any segments yet.

  2. Start looping through the string using enumerate to get both index i and character c.

  3. Iteration 1: i = 0, c = ' '. Since c is a space, we skip it.

  4. Iteration 2: i = 1, c = ' '. Another space, we skip it again.

  5. Iteration 3: i = 2, c = 'A'. This character is not a space, and since the preceding character is a space, it signifies the start of a new segment. We increment ans to 1.

  6. Iterations 4-10: These iterations deal with characters l, g, o, , E, x, p. Except these characters, none starts a new segment since they're either part of the current segment or they're space followed by another space.

  7. Iteration 11: i = 10, c = 'E'. This isn't a space. The preceding character is a space, so we've found a new segment. Increment ans to 2.

  8. Continue iterating through the rest of the string. We find no more starting points for a segment since all remaining characters are either part of an ongoing segment or are trailing spaces.

  9. By the end, we've identified that ans = 2, which means there are two segments in our example string s.

This walk-through demonstrates how the algorithm intelligently counts segments in a string by spotting those specific transitions from space to non-space characters (and also accounts for the first character if it's not a space). The count is then returned as the output.

Solution Implementation

1class Solution:
2    def count_segments(self, s: str) -> int:
3        # Initialize a counter for the number of segments
4        segment_count = 0
5      
6        # Iterate through the string character by character along with their index
7        for index, char in enumerate(s):
8            # Check if the character is not a space, and it's the start of a segment
9            # A new segment starts either at the beginning of the string (index == 0) 
10            # or just after a space character (s[index - 1] == ' ')
11            if char != ' ' and (index == 0 or s[index - 1] == ' '):
12                segment_count += 1  # Increment the segment count
13
14        # Return the total number of segments found
15        return segment_count
16
1class Solution {
2    public int countSegments(String s) {
3        // Initialize a variable to hold the count of segments
4        int segmentCount = 0;
5      
6        // Iterate over each character in the string
7        for (int i = 0; i < s.length(); ++i) {
8            // Check if the current character is not a space and if it is either the first character 
9            // or the character before it was a space (indicating the start of a new segment)
10            if (s.charAt(i) != ' ' && (i == 0 || s.charAt(i - 1) == ' ')) {
11                // Increment the segment count
12                ++segmentCount;
13            }
14        }
15      
16        // Return the total count of segments in the string
17        return segmentCount;
18    }
19}
20
1class Solution {
2public:
3    // Function to count the number of segments in a string,
4    // where a segment is defined as a contiguous sequence of non-space characters.
5    int countSegments(string s) {
6        int segmentCount = 0; // Initialize a count of segments to 0
7
8        // Loop through each character of the string
9        for (int i = 0; i < s.size(); ++i) {
10            // Check if the current character is not a space character
11            // and it is either the first character or preceded by a space
12            if (s[i] != ' ' && (i == 0 || s[i - 1] == ' ')) {
13                ++segmentCount;  // If true, increment the segment count
14            }
15        }
16
17        // Return the total number of segments found in the string
18        return segmentCount;
19    }
20};
21
1// Function to count the number of segments in a string,
2// where a segment is defined as a contiguous sequence of non-space characters.
3function countSegments(s: string): number {
4    let segmentCount = 0; // Initialize a count of segments to 0
5
6    // Loop through each character of the string
7    for (let i = 0; i < s.length; i++) {
8        // Check if the current character is not a space character
9        // and it is either the first character or preceded by a space
10        if (s[i] !== ' ' && (i === 0 || s[i - 1] === ' ')) {
11            segmentCount++;  // If true, increment the segment count
12        }
13    }
14
15    // Return the total number of segments found in the string
16    return segmentCount;
17}
18
Not Sure What to Study? Take the 2-min Quiz:

Which of the following problems can be solved with backtracking (select multiple)

Time and Space Complexity

The time complexity of the provided code snippet is O(n), where n is the length of the string s. This is because the code iterates once over all the characters in the string to count the number of segments. The conditional checks inside the loop are all O(1) operations, and they do not change the overall linear time complexity.

As for the space complexity, the provided code snippet uses O(1) extra space. The variable ans is the only additional space used that holds the count of segments. The space used does not grow with the size of the input string s, which means it is constant space complexity.

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

Fast Track Your Learning with Our Quick Skills Quiz:

Given a sorted array of integers and an integer called target, find the element that equals to the target and return its index. Select the correct code that fills the ___ in the given code snippet.

1def binary_search(arr, target):
2    left, right = 0, len(arr) - 1
3    while left ___ right:
4        mid = (left + right) // 2
5        if arr[mid] == target:
6            return mid
7        if arr[mid] < target:
8            ___ = mid + 1
9        else:
10            ___ = mid - 1
11    return -1
12
1public static int binarySearch(int[] arr, int target) {
2    int left = 0;
3    int right = arr.length - 1;
4
5    while (left ___ right) {
6        int mid = left + (right - left) / 2;
7        if (arr[mid] == target) return mid;
8        if (arr[mid] < target) {
9            ___ = mid + 1;
10        } else {
11            ___ = mid - 1;
12        }
13    }
14    return -1;
15}
16
1function binarySearch(arr, target) {
2    let left = 0;
3    let right = arr.length - 1;
4
5    while (left ___ right) {
6        let mid = left + Math.trunc((right - left) / 2);
7        if (arr[mid] == target) return mid;
8        if (arr[mid] < target) {
9            ___ = mid + 1;
10        } else {
11            ___ = mid - 1;
12        }
13    }
14    return -1;
15}
16

Recommended Readings


Got a question? Ask the Teaching Assistant anything you don't understand.

Still not clear? Ask in the Forum,  Discord or Submit the part you don't understand to our editors.


TA 👨‍🏫