2215. Find the Difference of Two Arrays - Explanation

Problem Link

Description

You are given two 0-indexed integer arrays nums1 and nums2, return a list answer of size 2 where:

  • answer[0] is a list of all distinct integers in nums1 which are not present in nums2.
  • answer[1] is a list of all distinct integers in nums2 which are not present in nums1.

Note that the integers in the lists may be returned in any order.

Example 1:

Input: nums1 = [1,2,3], nums2 = [2,4,6]

Output: [[1,3],[4,6]]

Example 2:

Input: nums1 = [1,2,3,3], nums2 = [1,1,2,2]

Output: [[3],[]]

Constraints:

  • 1 <= nums1.length, nums2.length <= 1000
  • -1000 <= nums1[i], nums2[i] <= 1000


Topics


Prerequisites

Before attempting this problem, you should be comfortable with:

  • Hash Sets - The optimal solution uses sets for O(1) lookup and set difference operations
  • Set Operations - Understanding union, intersection, and difference of sets
  • Two Pointers - Used in the sorting-based approach to efficiently compare sorted arrays

1. Brute Force

Intuition

The most straightforward approach is to check each element in one array against every element in the other array. For each number in nums1, we scan through all of nums2 to see if it exists there. If not found, it belongs in our result. We repeat the same process for nums2. Using sets ensures we only include each distinct value once.

Algorithm

  1. Initialize two empty sets to store unique elements that don't appear in the other array.
  2. For each element in nums1, iterate through nums2 to check if it exists. If not found, add it to the first result set.
  3. For each element in nums2, iterate through nums1 to check if it exists. If not found, add it to the second result set.
  4. Convert both sets to lists and return them.
class Solution:
    def findDifference(self, nums1: list[int], nums2: list[int]) -> list[list[int]]:
        res = [set(), set()]

        for num1 in nums1:
            found = False
            for num2 in nums2:
                if num1 == num2:
                    found = True
                    break
            if not found:
                res[0].add(num1)

        for num2 in nums2:
            found = False
            for num1 in nums1:
                if num1 == num2:
                    found = True
                    break
            if not found:
                res[1].add(num2)

        return [list(res[0]), list(res[1])]

Time & Space Complexity

  • Time complexity: O(nm)O(n * m)
  • Space complexity: O(n+m)O(n + m)

Where nn is the size of the array nums1nums1 and mm is the size of the array nums2nums2.


2. Sorting

Intuition

By sorting both arrays, we can efficiently compare elements using a two-pointer technique. After sorting, elements are ordered, so we can walk through both arrays simultaneously. When we find an element in one array that doesn't have a match at the current position in the other, we know it's unique without needing to scan the entire array.

Algorithm

  1. Sort both input arrays.
  2. Define a helper function that finds elements in array A that don't exist in array B:
    • Use a pointer j to track position in B.
    • For each unique element in A, advance j in B until we reach an element greater than or equal to the current element.
    • If B is exhausted or B[j] doesn't match, the element is unique to A.
  3. Call the helper function twice: once to find elements unique to nums1, and once for nums2.
  4. Return both result lists.
class Solution:
    def findDifference(self, nums1: list[int], nums2: list[int]) -> list[list[int]]:
        nums1.sort()
        nums2.sort()

        def helper(A, B):
            n, m = len(A), len(B)
            res = []

            j = 0
            prev = float('-inf')
            for num in A:
                if prev == num:
                    continue
                while j < m and B[j] < num:
                    j += 1
                if j == m or B[j] != num:
                    res.append(num)
                prev = num
            return res

        return [helper(nums1, nums2), helper(nums2, nums1)]

Time & Space Complexity

  • Time complexity: O(nlogn+mlogm)O(n \log n + m \log m)
  • Space complexity: O(1)O(1) or O(n+m)O(n + m) depending on the sorting algorithm.

Where nn is the size of the array nums1nums1 and mm is the size of the array nums2nums2.


3. Hash Set

Intuition

Hash sets provide O(1) average lookup time, making them ideal for membership testing. By converting both arrays to sets, we eliminate duplicates and can quickly check whether any element exists in the other array. This avoids the nested loops of the brute force approach.

Algorithm

  1. Convert nums1 and nums2 into hash sets to remove duplicates and enable fast lookups.
  2. Create an empty list for elements in nums1 that aren't in nums2.
  3. Iterate through the first set and add elements not found in the second set.
  4. Repeat for elements in the second set that aren't in the first set.
  5. Return both result lists.
class Solution:
    def findDifference(self, nums1: List[int], nums2: List[int]) -> List[List[int]]:
        num1Set, num2Set = set(nums1), set(nums2)
        res1, res2 = [], []

        for num in num1Set:
            if num not in num2Set:
                res1.append(num)

        for num in num2Set:
            if num not in num1Set:
                res2.append(num)

        return [res1, res2]

Time & Space Complexity

  • Time complexity: O(n+m)O(n + m)
  • Space complexity: O(n+m)O(n + m)

Where nn is the size of the array nums1nums1 and mm is the size of the array nums2nums2.


4. Hash Set Difference

Intuition

Many programming languages provide built-in set difference operations. The set difference A - B returns all elements in A that are not in B. This is exactly what the problem asks for, so we can leverage these optimized library functions for a clean, concise solution.

Algorithm

  1. Convert both arrays to sets.
  2. Compute the set difference of set1 minus set2 to get elements unique to nums1.
  3. Compute the set difference of set2 minus set1 to get elements unique to nums2.
  4. Convert both results to lists and return them.
class Solution:
    def findDifference(self, nums1: List[int], nums2: List[int]) -> List[List[int]]:
        numSet1, numSet2 = set(nums1), set(nums2)
        return [list(numSet1 - numSet2), list(numSet2 - numSet1)]

Time & Space Complexity

  • Time complexity: O(n+m)O(n + m)
  • Space complexity: O(n+m)O(n + m)

Where nn is the size of the array nums1nums1 and mm is the size of the array nums2nums2.


Common Pitfalls

Returning Duplicate Values in the Result

The problem asks for distinct integers. If you iterate through the original arrays instead of sets, you might add the same value multiple times to your result. Always use sets or track seen values to ensure each element appears only once in the output.

Confusing Which Array Each Result Belongs To

The output is a list of two lists: the first contains elements in nums1 but not in nums2, and the second contains elements in nums2 but not in nums1. Swapping these leads to incorrect results. Double-check which difference operation corresponds to which result list.