Data Structure Design for Two Sum III

Last Updated : 27 May, 2024

You have to design a data structure that accepts a stream of integers and then checks if it has a pair of integers that added/sum up to a particular value.

Implement the TwoSum class:

  • TwoSum(): Initializes the TwoSum object, with an empty array initially.
  • void add(int number): Adds number to the data structure.
  • boolean find(int value): Returns true if there exists any pair of numbers whose sum is equal to value, otherwise, it returns false.

Example:

Input: ["TwoSum", "add", "add", "add", "find", "find"]
[[], [1], [3], [5], [4], [7]]
Output: [null, null, null, null, true, false]
Explanation:

The TwoSum class is initialized with an empty array. The following operations are performed:

  • add(1): The array now contains [1].
  • add(3): The array now contains [1, 3].
  • add(5): The array now contains [1, 3, 5].
  • find(4): The sum of 1 and 3 is 4, so the method returns true.
  • find(7): There are no two integers in the array that sum up to 7, so the method returns false.

Approach:

Use a map to store the number count as they come. This will be useful to 1. access values in constant time, and 2. know how many times a number has been repeated in the stream.

Then we iterate the map, looking for the complement number that would equal value if added with the current number. That is, lookng for complement = value - currentnumber. If we find such complement in the map, return true.

Since we are looking for two numbers that equal value, if the complement is the same as the current number, it can only be true if this number has been seen more than once, therefore if numbercount > 1.

Steps-by-step approach:

  • Use an unordered_map to store the numbers and their counts.
  • In the add() function, increment the count of the given number in the map.
  • In the find() function:
    • Iterate through the map.
    • For each number num, calculate the complement complement = value - num.
    • Check if:
      • num == complement and count > 1 (meaning the number appears at least twice)
      • num != complement and complement exists in the map
    • If either condition is true, return true (because two numbers sum up to the target value).
  • If no two numbers sum up to the target value, return false.

Below is the Implementation of the above approach:

C++
#include <bits/stdc++.h>
using namespace std;

class TwoSum {
public:
    // Unordered map to store the numbers and their counts
    // Key: number, Value: count of the number
    unordered_map<int, int> seen;

    TwoSum()
    {
        // Constructor, initializes the unordered map
    }

    // Adds a number to the data structure
    void add(int number) { seen[number]++; }

    // Checks if there are two integers in the data
    // structure that sum up to the given value
    bool find(int value)
    {
        for (auto it : seen) {
            int num = it.first;
            int count = it.second;
            int complement = value - num;

            // If the complement is the same as the current
            // number and its count is greater than 1, then
            // there are two numbers that sum up to the
            // given value
            if ((num == complement && count > 1)
                || (num != complement
                    && seen.find(complement)
                           != seen.end())) {
                return true;
            }
        }

        // If no two numbers sum up to the given value,
        // return false
        return false;
    }
};

int main()
{
    TwoSum* obj = new TwoSum();
    obj->add(1);
    obj->add(3);
    obj->add(5);
    bool param2 = obj->find(4);
    cout << "Found sum of 4: " << param2 << endl;

    param2 = obj->find(7);
    cout << "Found sum of 7: " << param2 << endl;
    delete obj;
    return 0;
}
Java
import java.util.HashMap;
import java.util.Map;

class TwoSum {
    private Map<Integer, Integer> seen;

    public TwoSum() { seen = new HashMap<>(); }

    public void add(int number)
    {
        seen.put(number, seen.getOrDefault(number, 0) + 1);
    }

    public boolean find(int value)
    {
        for (Map.Entry<Integer, Integer> entry :
             seen.entrySet()) {
            int num = entry.getKey();
            int count = entry.getValue();
            int complement = value - num;

            if ((num == complement && count > 1)
                || (num != complement
                    && seen.containsKey(complement))) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args)
    {
        TwoSum obj = new TwoSum();
        obj.add(1);
        obj.add(3);
        obj.add(5);

        boolean param2 = obj.find(4);
        System.out.println("Found sum of 4: " + param2);

        param2 = obj.find(7);
        System.out.println("Found sum of 7: " + param2);
    }
}
Python
class TwoSum:
    def __init__(self):
        # Dictionary to store the numbers and their counts
        # Key: number, Value: count of the number
        self.seen = {}

    # Adds a number to the data structure
    def add(self, number):
        if number in self.seen:
            self.seen[number] += 1
        else:
            self.seen[number] = 1

    # Checks if there are two integers in the data structure that sum up to the given value
    def find(self, value):
        for num, count in self.seen.items():
            complement = value - num

            # If the complement is the same as the current number and its count is greater than 1,
            # then there are two numbers that sum up to the given value
            if (num == complement and count > 1) or (num != complement and complement in self.seen):
                return True

        # If no two numbers sum up to the given value, return False
        return False


# Main function
if __name__ == "__main__":
    obj = TwoSum()
    obj.add(1)
    obj.add(3)
    obj.add(5)
    param2 = obj.find(4)
    print("Found sum of 4:", param2)

    param2 = obj.find(7)
    print("Found sum of 7:", param2)
JavaScript
class TwoSum {
    constructor() {
        this.seen = new Map();
    }

    add(number) {
        this.seen.set(number, (this.seen.get(number) || 0) + 1);
    }

    find(value) {
        for (let [num, count] of this.seen.entries()) {
            let complement = value - num;

            if ((num === complement && count > 1) || (num !== complement && this.seen.has(complement))) {
                return true;
            }
        }
        return false;
    }
}

// Main execution starts here
const obj = new TwoSum();
obj.add(1);
obj.add(3);
obj.add(5);

let param2 = obj.find(4);
console.log("Found sum of 4:", param2);

param2 = obj.find(7);
console.log("Found sum of 7:", param2);

Output
Found sum of 4: 1
Found sum of 7: 0
  • Time complexity:
    • add() function: O(1),
    • find() function is O(n), where n is the number of unique elements in the data structure.
  • Auxiliary space: O(n), as the unordered_map used to store the numbers and their counts has a space complexity of O(n).
Comment