Difficulty: Easy | Acceptance: 76.10% | Paid: No Topics: Array, String
You are given an array of strings words and a character separator.
Split each string in words by separator.
Return a 2D array result containing the generated strings.
If a resulting string is empty, do not include it.
- Examples
- Constraints
- Approach 1: Built-in Split Functions
- Approach 2: Manual Iteration
Examples
Example 1:
Input: words = ["one.two.three","four.five","six"], separator = "."
Output: [["one","two","three"],["four","five"],["six"]]
Explanation:
"one.two.three" is split by "." into ["one", "two", "three"].
"four.five" is split by "." into ["four", "five"].
"six" is split by "." into ["six"].
Example 2:
Input: words = ["$easy$","$problem$"], separator = "$"
Output: [["easy"],["problem"]]
Explanation:
"$easy$" is split by "$" into ["", "easy", ""]. We only include "easy".
"$problem$" is split by "$" into ["", "problem", ""]. We only include "problem".
Example 3:
Input: words = ["|||"], separator = "|"
Output: [[]]
Explanation:
"|||" is split by "|" into ["", "", "", ""]. All strings are empty, so we return an empty array [].
Constraints
1 <= words.length <= 100
1 <= words[i].length <= 20
words[i] consists of lowercase English letters, uppercase English letters, and separator.
separator is a character.
Approach 1: Built-in Split Functions
Intuition Most modern programming languages provide a built-in method to split strings by a delimiter. We can iterate through the input list, apply the split function to each string, and filter out any empty strings that result from the split operation.
Steps
- Initialize an empty list
resultto store the final 2D array. - Iterate through each string
wordin the input listwords. - Use the languageās built-in split function to divide
wordby theseparator. - Filter the resulting array/list to remove any empty strings.
- Append the filtered list to
result. - Return
result.
class Solution:
def splitWordsBySeparator(self, words: list[str], separator: str) -> list[list[str]]:
result = []
for word in words:
# Split by separator and filter out empty strings
parts = [part for part in word.split(separator) if part]
result.append(parts)
return resultComplexity
- Time: O(N * L), where N is the number of words and L is the average length of a word. Splitting a string and iterating over its parts takes linear time relative to the string length.
- Space: O(N * L) to store the resulting 2D array.
- Notes: This approach is concise and leverages optimized standard library functions. In Java, care must be taken to escape the separator if it is a regex metacharacter.
Approach 2: Manual Iteration
Intuition We can manually iterate through each character of every string to build the substrings ourselves. This avoids the overhead of regular expressions (in languages like Java) or creating intermediate arrays, offering fine-grained control over the splitting process.
Steps
- Initialize an empty list
result. - Iterate through each string
wordinwords. - Initialize an empty list
currentPartsand an empty stringcurrentWord. - Iterate through each character
cinword:- If
cmatches theseparator:- If
currentWordis not empty, add it tocurrentParts. - Reset
currentWordto an empty string.
- If
- Otherwise, append
ctocurrentWord.
- If
- After the loop finishes, check if
currentWordis not empty. If so, add it tocurrentParts(to handle the last segment). - Append
currentPartstoresult. - Return
result.
class Solution:
def splitWordsBySeparator(self, words: list[str], separator: str) -> list[list[str]]:
result = []
for word in words:
current_parts = []
current_word = []
for char in word:
if char == separator:
if current_word:
current_parts.append(''.join(current_word))
current_word = []
else:
current_word.append(char)
# Add the last segment if it exists
if current_word:
current_parts.append(''.join(current_word))
result.append(current_parts)
return resultComplexity
- Time: O(N * L), where N is the number of words and L is the average length of a word. We visit each character exactly once.
- Space: O(N * L) to store the output. In the worst case (no separators), the output size is proportional to the input size.
- Notes: This approach is generally more efficient in languages where string splitting involves regex or heavy memory allocation, as it allows for single-pass processing.