Problem

Given two string arrays words1 and words2, return the number of strings that appearexactly once in each of the two arrays.

Examples

Example 1

1
2
3
4
5
6
7
8
Input: words1 = ["leetcode","is","amazing","as","is"], words2 = ["amazing","leetcode","is"]
Output: 2
Explanation:
- "leetcode" appears exactly once in each of the two arrays. We count this string.
- "amazing" appears exactly once in each of the two arrays. We count this string.
- "is" appears in each of the two arrays, but there are 2 occurrences of it in words1. We do not count this string.
- "as" appears once in words1, but does not appear in words2. We do not count this string.
Thus, there are 2 strings that appear exactly once in each of the two arrays.

Example 2

1
2
3
Input: words1 = ["b","bb","bbb"], words2 = ["a","aa","aaa"]
Output: 0
Explanation: There are no strings that appear in each of the two arrays.

Example 3

1
2
3
Input: words1 = ["a","ab"], words2 = ["a","a","a","ab"]
Output: 1
Explanation: The only string that appears exactly once in each of the two arrays is "ab".

Constraints

  • 1 <= words1.length, words2.length <= 1000
  • 1 <= words1[i].length, words2[j].length <= 30
  • words1[i] and words2[j] consists only of lowercase English letters.

Solution

Method 1 – Hash Map Counting

Intuition

If a word appears exactly once in both arrays, it is counted. We can use hash maps to count occurrences in each array, then count words that have a count of 1 in both.

Approach

  1. Use a hash map to count occurrences of each word in words1.
  2. Use another hash map to count occurrences in words2.
  3. For each word in the first map, if it appears exactly once in both maps, increment the answer.
  4. Return the answer.

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
public:
    int countWords(vector<string>& w1, vector<string>& w2) {
        unordered_map<string, int> m1, m2;
        for (auto& w : w1) m1[w]++;
        for (auto& w : w2) m2[w]++;
        int ans = 0;
        for (auto& [k, v] : m1) {
            if (v == 1 && m2[k] == 1) ans++;
        }
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
func countWords(w1 []string, w2 []string) int {
    m1 := map[string]int{}
    m2 := map[string]int{}
    for _, w := range w1 { m1[w]++ }
    for _, w := range w2 { m2[w]++ }
    ans := 0
    for k, v := range m1 {
        if v == 1 && m2[k] == 1 {
            ans++
        }
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    public int countWords(String[] w1, String[] w2) {
        Map<String, Integer> m1 = new HashMap<>(), m2 = new HashMap<>();
        for (String w : w1) m1.put(w, m1.getOrDefault(w, 0) + 1);
        for (String w : w2) m2.put(w, m2.getOrDefault(w, 0) + 1);
        int ans = 0;
        for (String k : m1.keySet()) {
            if (m1.get(k) == 1 && m2.getOrDefault(k, 0) == 1) ans++;
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Solution {
    fun countWords(w1: Array<String>, w2: Array<String>): Int {
        val m1 = mutableMapOf<String, Int>()
        val m2 = mutableMapOf<String, Int>()
        for (w in w1) m1[w] = m1.getOrDefault(w, 0) + 1
        for (w in w2) m2[w] = m2.getOrDefault(w, 0) + 1
        var ans = 0
        for ((k, v) in m1) {
            if (v == 1 && m2.getOrDefault(k, 0) == 1) ans++
        }
        return ans
    }
}
1
2
3
4
5
6
class Solution:
    def countWords(self, w1: list[str], w2: list[str]) -> int:
        from collections import Counter
        c1 = Counter(w1)
        c2 = Counter(w2)
        return sum(1 for k in c1 if c1[k] == 1 and c2.get(k, 0) == 1)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
use std::collections::HashMap;
impl Solution {
    pub fn count_words(w1: Vec<String>, w2: Vec<String>) -> i32 {
        let mut m1 = HashMap::new();
        let mut m2 = HashMap::new();
        for w in w1.iter() { *m1.entry(w).or_insert(0) += 1; }
        for w in w2.iter() { *m2.entry(w).or_insert(0) += 1; }
        let mut ans = 0;
        for (k, v) in m1.iter() {
            if *v == 1 && *m2.get(k).unwrap_or(&0) == 1 { ans += 1; }
        }
        ans
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
    countWords(w1: string[], w2: string[]): number {
        const m1: Record<string, number> = {}, m2: Record<string, number> = {};
        for (const w of w1) m1[w] = (m1[w] || 0) + 1;
        for (const w of w2) m2[w] = (m2[w] || 0) + 1;
        let ans = 0;
        for (const k in m1) {
            if (m1[k] === 1 && m2[k] === 1) ans++;
        }
        return ans;
    }
}

Complexity

  • ⏰ Time complexity: O(n + m), where n and m are the lengths of the two arrays, for counting and checking.
  • 🧺 Space complexity: O(n + m), for storing the counts in hash maps.