How would you reverse the order of words in a given string, handling various space scenarios, and what are the complexities involved?

Hard
7 years ago

Let's explore some string manipulation algorithms. Suppose you are given a string s and you need to reverse the order of words in the string. Each word is separated by a single space, and there are no leading or trailing spaces. For example, if the input string s is "the sky is blue", the expected output is "blue is sky the".

  1. Write a function that takes a string s as input and returns a new string with the words in reversed order.
  2. Explain your approach. What is the time and space complexity of your algorithm?
  3. Provide example test cases to demonstrate that your function works correctly, including edge cases such as an empty string or a string with only one word.

As a follow-up, consider a more complex scenario where the input string s might contain leading or trailing spaces, or multiple spaces between words. How would you modify your algorithm to handle these cases while still producing the correct reversed word order? For instance, given the input " hello world ", the output should be "world hello". Describe the changes needed and analyze the updated time and space complexity.

Sample Answer

String Manipulation: Reversing Words in a String

This response addresses the interview question regarding string manipulation, specifically reversing the order of words in a given string. It includes a function to reverse the words, explains the approach with time and space complexity analysis, provides test cases, and discusses handling edge cases like leading/trailing spaces and multiple spaces between words.

1. Function to Reverse Words

def reverse_words(s):
    words = s.split()
    reversed_words = words[::-1]
    return " ".join(reversed_words)

2. Explanation of Approach

The approach involves the following steps:

  1. Split the string: The input string s is split into a list of words using the split() method. By default, split() splits the string by spaces.
  2. Reverse the list: The list of words is reversed using slicing [::-1]. This creates a new reversed list.
  3. Join the words: The reversed list of words is joined back into a string, with each word separated by a single space, using the join() method.

Time Complexity

  • split(): O(n), where n is the length of the string.
  • Reversing the list [::-1]: O(n), as it creates a reversed copy of the list.
  • join(): O(n), where n is the total length of the final string (sum of the lengths of the words plus the spaces).

Therefore, the overall time complexity is O(n).

Space Complexity

  • split(): O(n), as it creates a list of words that, in the worst case (if the string contains only one word), can have length n. In the average case, the space will be proportional to the number of words, which is still bounded by n.
  • Reversed List: O(n), as it creates a new list with the same number of elements as the original list of words.

Therefore, the overall space complexity is O(n).

3. Example Test Cases

print(reverse_words("the sky is blue"))  # Output: blue is sky the
print(reverse_words("hello world"))      # Output: world hello
print(reverse_words("a"))                # Output: a
print(reverse_words(""))                 # Output: ""

Follow-up: Handling Leading/Trailing Spaces and Multiple Spaces

To handle leading/trailing spaces and multiple spaces between words, we can modify the split() method and add a preprocessing step. The split() method, when called without arguments, automatically removes leading and trailing spaces and treats multiple spaces as a single delimiter.

Here's the modified function:

def reverse_words_advanced(s):
    words = s.split()
    reversed_words = words[::-1]
    return " ".join(reversed_words)

This version works correctly because s.split() handles the extra spaces automatically.

Example Test Cases with Edge Cases

print(reverse_words_advanced("  hello   world  "))  # Output: world hello
print(reverse_words_advanced("the   sky is blue"))   # Output: blue is sky the
print(reverse_words_advanced(" a b "))              # Output: b a
print(reverse_words_advanced("   "))                  # Output: ""

Updated Time and Space Complexity

The time and space complexity remain O(n), where n is the length of the input string. The split() method still iterates through the string, and the reversing and joining operations are still proportional to the number of words, which is bounded by the length of the string.