{x}
blog image

Check If Two String Arrays are Equivalent

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: false

Example 3:

Input: word1  = ["abc", "d", "defg"], word2 = ["abcddefg"]
Output: true

 

Constraints:

  • 1 <= word1.length, word2.length <= 103
  • 1 <= word1[i].length, word2[i].length <= 103
  • 1 <= sum(word1[i].length), sum(word2[i].length) <= 103
  • word1[i] and word2[i] consist of lowercase letters.

Solution Explanation for Check If Two String Arrays are Equivalent

This problem asks whether two arrays of strings represent the same string when their elements are concatenated. We can solve this efficiently using two main approaches: string concatenation and direct traversal.

Approach 1: String Concatenation

This is the simpler and more concise approach. We use the built-in string joining functions in each language to concatenate the strings within each array into a single string. Then, we simply compare these two resulting strings for equality.

Code Examples:

The code snippets below demonstrate this approach in various programming languages. The core logic remains the same: join the strings in each array and compare the results.

class Solution:
    def arrayStringsAreEqual(self, word1: List[str], word2: List[str]) -> bool:
        return ''.join(word1) == ''.join(word2)
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) {
        string s1 = "";
        for (const string& s : word1) s1 += s;
        string s2 = "";
        for (const string& s : word2) s2 += s;
        return s1 == s2;
    }
};

(Other languages will have similar implementations using their respective string joining functions.)

Time Complexity: O(m), where m is the total number of characters across all strings in both arrays. This is because string concatenation has a linear time complexity with respect to the string lengths.

Space Complexity: O(m) in the worst case. This is because we create two new strings in memory to store the concatenated results.

Approach 2: Direct Traversal (Pointer-Based)

This approach avoids the extra space overhead of string concatenation by directly iterating through the character arrays and comparing characters one by one.

Code Examples:

This approach uses multiple index pointers:

  • i, j: Indices for iterating through word1 and word2 arrays respectively.
  • x, y: Indices to iterate within the individual strings of word1[i] and word2[j].
class Solution:
    def arrayStringsAreEqual(self, word1: List[str], word2: List[str]) -> bool:
        i = j = x = y = 0
        while i < len(word1) and j < len(word2):
            if word1[i][x] != word2[j][y]:
                return False
            x += 1
            y += 1
            if x == len(word1[i]):
                x = 0
                i += 1
            if y == len(word2[j]):
                y = 0
                j += 1
        return i == len(word1) and j == len(word2)
 
class Solution {
    public boolean arrayStringsAreEqual(String[] word1, String[] word2) {
        int i = 0, j = 0;
        int x = 0, y = 0;
        while (i < word1.length && j < word2.length) {
            if (word1[i].charAt(x++) != word2[j].charAt(y++)) {
                return false;
            }
            if (x == word1[i].length()) {
                x = 0;
                ++i;
            }
            if (y == word2[j].length()) {
                y = 0;
                ++j;
            }
        }
        return i == word1.length && j == word2.length;
    }
}

(Other languages will have similar implementations.)

Time Complexity: O(m), same as Approach 1, because we still iterate through all characters.

Space Complexity: O(1). We only use a constant number of integer variables for indexing, regardless of the input size. This makes it more space-efficient than Approach 1.

Conclusion:

Both approaches solve the problem correctly. Approach 2 (direct traversal) is generally preferred because it's more space-efficient, especially when dealing with very large input arrays. Approach 1 is more concise and readable, but might consume more memory for very large inputs. The choice depends on the specific needs and constraints of your application.