Check If Two String Arrays are Equivalent
EasyPrompt
Given two string arrays word1 and word2, return true if the two arrays represent the same string, and false otherwise.
A string is represented by an array if the array elements concatenated in order forms the string.
Example 1:
Input: word1 = ["ab", "c"], word2 = ["a", "bc"]
Output: true
Explanation:
word1 represents string "ab" + "c" -> "abc"
word2 represents string "a" + "bc" -> "abc"
The strings are the same, so return true.Example 2:
Input: word1 = ["a", "cb"], word2 = ["ab", "c"]
Output: falseExample 3:
Input: word1 = ["abc", "d", "defg"], word2 = ["abcddefg"]
Output: true
Constraints:
1 <= word1.length, word2.length <= 1031 <= word1[i].length, word2[i].length <= 1031 <= sum(word1[i].length), sum(word2[i].length) <= 103word1[i]andword2[i]consist of lowercase letters.
Approaches
2 approaches with complexity analysis and trade-offs.
This approach involves creating the two complete strings by concatenating the elements of each array and then comparing the resulting strings.
Algorithm
- Create a
StringBuildersb1. - Iterate through
word1and append each string tosb1. - Create a
StringBuildersb2. - Iterate through
word2and append each string tosb2. - Return the result of
sb1.toString().equals(sb2.toString()).
Walkthrough
The idea is to simulate the process described in the problem directly. We build two strings, one for each input array.
- Initialize two
StringBuilderobjects,sb1andsb2. - Iterate through the
word1array. For each stringsinword1, append it tosb1. - Iterate through the
word2array. For each stringsinword2, append it tosb2. - After building both strings, convert the
StringBuilderobjects toStringobjects. - Compare the two resulting strings using the
.equals()method. If they are identical, returntrue; otherwise, returnfalse.
class Solution { public boolean arrayStringsAreEqual(String[] word1, String[] word2) { StringBuilder sb1 = new StringBuilder(); for (String s : word1) { sb1.append(s); } StringBuilder sb2 = new StringBuilder(); for (String s : word2) { sb2.append(s); } return sb1.toString().equals(sb2.toString()); }}A more concise way to write this in Java using String.join:
class Solution { public boolean arrayStringsAreEqual(String[] word1, String[] word2) { return String.join("", word1).equals(String.join("", word2)); }}Complexity
Time
O(N + M), where N is the total number of characters in `word1` and M is the total number of characters in `word2`. We need to iterate through all characters to build the strings.
Space
O(N + M). We need extra space to store the two concatenated strings, where N is the total length of strings in `word1` and M is the total length of strings in `word2`.
Trade-offs
Pros
Very simple and intuitive to implement.
Code is clean and easy to read, especially with helpers like
String.join.
Cons
Inefficient in terms of space, as it requires creating copies of all the characters in memory.
Can be slow if the total length of strings is very large due to memory allocation.
This approach avoids creating the intermediate concatenated strings by comparing the characters one by one using pointers. This is significantly more memory-efficient.
Algorithm
- Initialize pointers for
word1(w1,c1) andword2(w2,c2) to0. - Use a
whileloop that continues as long asw1 < word1.lengthandw2 < word2.length. - Inside the loop, if
word1[w1].charAt(c1)is not equal toword2[w2].charAt(c2), returnfalse. - Increment
c1andc2. - If
c1is at the end ofword1[w1], incrementw1and resetc1to0. - If
c2is at the end ofword2[w2], incrementw2and resetc2to0. - After the loop, return
trueonly if bothw1has reached the end ofword1andw2has reached the end ofword2.
Walkthrough
Instead of building the full strings, we can simulate the comparison character by character. We use pointers to track our current position within the arrays of strings and within the strings themselves.
- Initialize four pointers:
w1(index forword1),c1(character index forword1[w1]),w2(index forword2), andc2(character index forword2[w2]). All start at 0. - Loop as long as both
w1andw2are within the bounds of their respective arrays. - Inside the loop, compare the characters:
word1[w1].charAt(c1)andword2[w2].charAt(c2). If they don't match, the strings are not equivalent, so returnfalse. - Increment both character pointers,
c1andc2. - If
c1reaches the end of the current stringword1[w1], it means we've finished this word. We move to the next word by incrementingw1and resettingc1to 0. - Similarly, if
c2reaches the end ofword2[w2], incrementw2and resetc2to 0. - After the loop terminates, it means we've exhausted at least one of the arrays. For the strings to be truly equal, both arrays must be fully traversed. We check if
w1has reached the end ofword1ANDw2has reached the end ofword2. If both conditions are true, it means they are equivalent. Otherwise, one is a prefix of the other, and they are not equal.
class Solution { public boolean arrayStringsAreEqual(String[] word1, String[] word2) { int w1 = 0, c1 = 0; // Pointers for word1 int w2 = 0, c2 = 0; // Pointers for word2 while (w1 < word1.length && w2 < word2.length) { // Get the current characters to compare char char1 = word1[w1].charAt(c1); char char2 = word2[w2].charAt(c2); if (char1 != char2) { return false; } // Move to the next character c1++; c2++; // If we reached the end of a string in word1, move to the next string if (c1 == word1[w1].length()) { w1++; c1 = 0; } // If we reached the end of a string in word2, move to the next string if (c2 == word2[w2].length()) { w2++; c2 = 0; } } // After the loop, both arrays must be fully traversed for the strings to be equal. return w1 == word1.length && w2 == word2.length; }}Complexity
Time
O(min(N, M)), where N and M are the total character counts. In the worst case (equal strings), it's O(N) as we traverse every character once. The comparison stops as soon as a mismatch is found.
Space
O(1). We only use a few integer variables for pointers, regardless of the input size.
Trade-offs
Pros
Extremely memory efficient (O(1) space).
Can be faster in practice if the strings differ early on, as it allows for early exit.
Cons
The implementation logic is more complex and requires careful handling of multiple pointers and boundary conditions.
Solutions
Solution
class Solution { public boolean arrayStringsAreEqual ( String [] word1 , String [] word2 ) { return String . join ( "" , word1 ). equals ( String . join ( "" , word2 )); } }class Solution { public: bool arrayStringsAreEqual ( vector < string >& word1 , vector < string >& word2 ) { return reduce ( word1 . cbegin (), word1 . cend ()) == reduce ( word2 . cbegin (), word2 . cend ()); } };class Solution : def arrayStringsAreEqual ( self , word1 : List [ str ], word2 : List [ str ]) -> bool : return '' . join ( word1 ) == '' . join ( word2 )Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.