# Check If Two String Arrays are Equivalent
**Difficulty:** EASY
[External](https://leetcode.com/problems/check-if-two-string-arrays-are-equivalent)
Canonical: https://scaleengineer.com/dsa/problems/check-if-two-string-arrays-are-equivalent
**Data structures:** Array, String
---
## Problem
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.

# Approaches
## String Concatenation
This approach involves creating the two complete strings by concatenating the elements of each array and then comparing the resulting strings.
**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`.
**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.
### Explanation
The idea is to simulate the process described in the problem directly. We build two strings, one for each input array.

1.  Initialize two `StringBuilder` objects, `sb1` and `sb2`.
2.  Iterate through the `word1` array. For each string `s` in `word1`, append it to `sb1`.
3.  Iterate through the `word2` array. For each string `s` in `word2`, append it to `sb2`.
4.  After building both strings, convert the `StringBuilder` objects to `String` objects.
5.  Compare the two resulting strings using the `.equals()` method. If they are identical, return `true`; otherwise, return `false`.

```java
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`:

```java
class Solution {
    public boolean arrayStringsAreEqual(String[] word1, String[] word2) {
        return String.join("", word1).equals(String.join("", word2));
    }
}
```
### Algorithm
- Create a `StringBuilder` `sb1`.
- Iterate through `word1` and append each string to `sb1`.
- Create a `StringBuilder` `sb2`.
- Iterate through `word2` and append each string to `sb2`.
- Return the result of `sb1.toString().equals(sb2.toString())`.

## Two Pointers Simulation
This approach avoids creating the intermediate concatenated strings by comparing the characters one by one using pointers. This is significantly more memory-efficient.
**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.
**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.
### Explanation
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.

1.  Initialize four pointers: `w1` (index for `word1`), `c1` (character index for `word1[w1]`), `w2` (index for `word2`), and `c2` (character index for `word2[w2]`). All start at 0.
2.  Loop as long as both `w1` and `w2` are within the bounds of their respective arrays.
3.  Inside the loop, compare the characters: `word1[w1].charAt(c1)` and `word2[w2].charAt(c2)`. If they don't match, the strings are not equivalent, so return `false`.
4.  Increment both character pointers, `c1` and `c2`.
5.  If `c1` reaches the end of the current string `word1[w1]`, it means we've finished this word. We move to the next word by incrementing `w1` and resetting `c1` to 0.
6.  Similarly, if `c2` reaches the end of `word2[w2]`, increment `w2` and reset `c2` to 0.
7.  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 `w1` has reached the end of `word1` AND `w2` has reached the end of `word2`. If both conditions are true, it means they are equivalent. Otherwise, one is a prefix of the other, and they are not equal.

```java
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;
    }
}
```
### Algorithm
- Initialize pointers for `word1` (`w1`, `c1`) and `word2` (`w2`, `c2`) to `0`.
- Use a `while` loop that continues as long as `w1 < word1.length` and `w2 < word2.length`.
- Inside the loop, if `word1[w1].charAt(c1)` is not equal to `word2[w2].charAt(c2)`, return `false`.
- Increment `c1` and `c2`.
- If `c1` is at the end of `word1[w1]`, increment `w1` and reset `c1` to `0`.
- If `c2` is at the end of `word2[w2]`, increment `w2` and reset `c2` to `0`.
- After the loop, return `true` only if both `w1` has reached the end of `word1` and `w2` has reached the end of `word2`.

# Solutions
### Java

```java
class Solution { public boolean arrayStringsAreEqual ( String [] word1 , String [] word2 ) { return String . join ( "" , word1 ). equals ( String . join ( "" , word2 )); } }
```

### CPP

```cpp
class Solution { public: bool arrayStringsAreEqual ( vector < string >& word1 , vector < string >& word2 ) { return reduce ( word1 . cbegin (), word1 . cend ()) == reduce ( word2 . cbegin (), word2 . cend ()); } };
```

### Python

```python
class Solution : def arrayStringsAreEqual ( self , word1 : List [ str ], word2 : List [ str ]) -> bool : return '' . join ( word1 ) == '' . join ( word2 )
```
