Facebook Pixel

2023. Number of Pairs of Strings With Concatenation Equal to Target

MediumArrayHash TableStringCounting
Leetcode Link

Problem Description

You are given an array of digit strings called nums and a digit string called target. Your task is to find how many pairs of indices (i, j) exist where:

  • i and j are different indices (meaning i != j)
  • When you concatenate nums[i] and nums[j] together (in that order), the result equals target

For example, if nums = ["7", "23", "77"] and target = "777", then:

  • nums[0] + nums[2] = "7" + "77" = "777" equals target (this counts as one pair)
  • nums[2] + nums[0] = "77" + "7" = "777" equals target (this counts as another pair)

Note that concatenation means joining two strings together. So "12" + "34" = "1234".

The solution uses a brute force approach by checking every possible pair of indices. It iterates through all combinations where i goes from 0 to n-1 and j goes from 0 to n-1, checking if i != j and if concatenating nums[i] with nums[j] produces the target string. The sum function counts how many such valid pairs exist.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The key insight is that we need to find all possible ways to split the target string into two parts, where each part comes from the nums array. Since we're looking for concatenations that form the target, we need to check every possible pairing.

Think about it this way: if target = "777", it could potentially be formed by:

  • "7" + "77"
  • "77" + "7"
  • "777" + "" (if empty string existed)
  • And so on...

Since we don't know in advance which elements in nums could be the first part or the second part of a valid concatenation, the most straightforward approach is to try all possibilities.

For each element at index i, we can pair it with any other element at index j (where i != j). We concatenate nums[i] with nums[j] and check if it matches our target. This naturally leads to a nested loop structure where we examine all n × n possible pairings, excluding cases where i == j since we need different indices.

The beauty of this approach is its simplicity - we don't need to preprocess the data or use complex string matching algorithms. We just systematically check every valid pair and count how many produce our target string. The use of a generator expression with sum() makes the implementation concise while maintaining clarity about what we're counting.

Solution Approach

The solution implements a brute force enumeration approach to solve this problem. Let's walk through the implementation step by step:

  1. Get the array length: First, we determine n = len(nums) to know the bounds for our iteration.

  2. Double loop enumeration: We use two nested loops to enumerate all possible pairs:

    • The outer loop variable i ranges from 0 to n-1
    • The inner loop variable j also ranges from 0 to n-1
    • This gives us all n × n possible combinations of indices
  3. Validation and counting: For each pair (i, j), we check two conditions:

    • i != j: Ensures we're using different indices as required
    • nums[i] + nums[j] == target: Checks if the concatenation matches our target string
  4. Sum the results: The solution uses Python's sum() function with a generator expression. The expression i != j and nums[i] + nums[j] == target evaluates to:

    • True (counts as 1) when both conditions are met
    • False (counts as 0) otherwise

The entire logic is compressed into a single line:

sum(i != j and nums[i] + nums[j] == target for i in range(n) for j in range(n))

This generator expression iterates through all pairs, evaluates the boolean condition for each, and sums up the True values (each True contributes 1 to the sum).

Time Complexity: O(n² × m) where n is the length of the array and m is the average length of strings (for string comparison)

Space Complexity: O(1) as we only use constant extra space (not counting the input)

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a concrete example to understand how the solution works.

Given:

  • nums = ["2", "4", "24", "42"]
  • target = "244"

We need to find all pairs (i, j) where i != j and nums[i] + nums[j] == "244".

Step-by-step execution:

Let's trace through each iteration of our nested loops:

ijnums[i]nums[j]ConcatenationEquals target?Count
00"2""2"-Skip (i == j)0
01"2""4""24"No0
02"2""24""224"No0
03"2""42""242"No0
10"4""2""42"No0
11"4""4"-Skip (i == j)0
12"4""24""424"No0
13"4""42""442"No0
20"24""2""242"No0
21"24""4""244"Yes!1
22"24""24"-Skip (i == j)1
23"24""42""2442"No1
30"42""2""422"No1
31"42""4""424"No1
32"42""24""4224"No1
33"42""42"-Skip (i == j)1

Result: We found exactly 1 valid pair: (i=2, j=1) where nums[2] + nums[1] = "24" + "4" = "244".

The solution efficiently checks all 16 possible combinations (4×4), skips the 4 cases where i equals j, and evaluates the remaining 12 concatenations. The sum() function counts each True result as 1, giving us our final answer of 1.

Solution Implementation

1class Solution:
2    def numOfPairs(self, nums: List[str], target: str) -> int:
3        """
4        Count the number of pairs (i, j) where i != j and 
5        concatenating nums[i] + nums[j] equals the target string.
6      
7        Args:
8            nums: List of strings to form pairs from
9            target: Target string to match with concatenated pairs
10          
11        Returns:
12            Number of valid pairs that concatenate to form target
13        """
14        n = len(nums)
15      
16        # Count all pairs where indices are different and concatenation equals target
17        # Using generator expression with sum to count True values (True = 1, False = 0)
18        count = sum(
19            i != j and nums[i] + nums[j] == target 
20            for i in range(n) 
21            for j in range(n)
22        )
23      
24        return count
25
1class Solution {
2    /**
3     * Counts the number of pairs (i, j) where i != j and 
4     * concatenating nums[i] + nums[j] equals the target string.
5     * 
6     * @param nums Array of strings to form pairs from
7     * @param target The target string to match with concatenated pairs
8     * @return The count of valid pairs
9     */
10    public int numOfPairs(String[] nums, String target) {
11        // Get the length of the input array
12        int arrayLength = nums.length;
13      
14        // Initialize counter for valid pairs
15        int pairCount = 0;
16      
17        // Iterate through all possible first elements
18        for (int i = 0; i < arrayLength; i++) {
19            // Iterate through all possible second elements
20            for (int j = 0; j < arrayLength; j++) {
21                // Check if indices are different and concatenation equals target
22                if (i != j && target.equals(nums[i] + nums[j])) {
23                    pairCount++;
24                }
25            }
26        }
27      
28        return pairCount;
29    }
30}
31
1class Solution {
2public:
3    int numOfPairs(vector<string>& nums, string target) {
4        // Get the size of the input array
5        int arraySize = nums.size();
6      
7        // Initialize counter for valid pairs
8        int pairCount = 0;
9      
10        // Iterate through each element as the first part of the pair
11        for (int i = 0; i < arraySize; ++i) {
12            // Iterate through each element as the second part of the pair
13            for (int j = 0; j < arraySize; ++j) {
14                // Check if indices are different and concatenation equals target
15                // nums[i] + nums[j] concatenates the two strings
16                if (i != j && nums[i] + nums[j] == target) {
17                    pairCount++;
18                }
19            }
20        }
21      
22        // Return the total count of valid pairs
23        return pairCount;
24    }
25};
26
1function numOfPairs(nums: string[], target: string): number {
2    // Get the size of the input array
3    const arraySize: number = nums.length;
4  
5    // Initialize counter for valid pairs
6    let pairCount: number = 0;
7  
8    // Iterate through each element as the first part of the pair
9    for (let i = 0; i < arraySize; i++) {
10        // Iterate through each element as the second part of the pair
11        for (let j = 0; j < arraySize; j++) {
12            // Check if indices are different and concatenation equals target
13            // nums[i] + nums[j] concatenates the two strings
14            if (i !== j && nums[i] + nums[j] === target) {
15                pairCount++;
16            }
17        }
18    }
19  
20    // Return the total count of valid pairs
21    return pairCount;
22}
23

Time and Space Complexity

Time Complexity: O(n^2 × m)

The code uses two nested loops, each iterating through all n elements of the nums array, resulting in n^2 iterations. For each iteration, the code performs:

  • String concatenation: nums[i] + nums[j] takes O(len(nums[i]) + len(nums[j])) time
  • String comparison: comparing the concatenated string with target takes O(m) time, where m is the length of the target string

In the worst case, the length of concatenated strings could be up to m (when they form the target), so each comparison takes O(m) time. Therefore, the overall time complexity is O(n^2 × m).

Space Complexity: O(m)

While the code doesn't explicitly create any data structures that grow with input size, the string concatenation operation nums[i] + nums[j] creates a new temporary string for each comparison. This temporary string can have a maximum length of m (the length of the target string). Although this temporary string is created and discarded in each iteration, at any given moment, the space used for this operation is O(m).

Note: The reference answer states O(1) space complexity, which would be valid if we consider only auxiliary space excluding the temporary strings created during concatenation. However, technically, the string concatenation does use O(m) space.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Counting Pairs Twice or Missing Order Sensitivity

A common mistake is misunderstanding that (i, j) and (j, i) are different pairs when the order matters in concatenation. Some might incorrectly optimize by only checking j > i to avoid "duplicates", but this would miss valid pairs.

Incorrect approach:

# WRONG: This only counts unordered pairs
count = sum(
    nums[i] + nums[j] == target 
    for i in range(n) 
    for j in range(i + 1, n)  # Only checking j > i misses valid pairs!
)

Why it's wrong: Since concatenation is order-dependent, nums[i] + nums[j] can be different from nums[j] + nums[i]. For example, "7" + "77" = "777" while "77" + "7" = "777" are both valid but distinct pairs.

Correct approach: Check all pairs where i != j, allowing both (i, j) and (j, i) to be counted separately.

2. Inefficient String Concatenation for Large Datasets

When dealing with large arrays or when the same elements appear multiple times, repeatedly concatenating strings can be inefficient.

Optimized solution using hash maps:

def numOfPairs(self, nums: List[str], target: str) -> int:
    count = 0
    freq = {}
  
    # Count frequency of each string
    for num in nums:
        freq[num] = freq.get(num, 0) + 1
  
    # Check each possible prefix
    for i in range(1, len(target)):
        prefix = target[:i]
        suffix = target[i:]
      
        if prefix in freq and suffix in freq:
            if prefix == suffix:
                # Same string used twice: n * (n-1) pairs
                count += freq[prefix] * (freq[prefix] - 1)
            else:
                # Different strings: n1 * n2 pairs
                count += freq[prefix] * freq[suffix]
  
    return count

This optimization reduces time complexity from O(n² × m) to O(n + m²) where m is the length of the target string, which is much better when n is large and m is relatively small.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

In a binary min heap, the minimum element can be found in:


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More