Facebook Pixel

Amazon Online Assessment (OA) - Two Sum - Unique Pairs

Write a function that takes a list of numbers and a target number, and then returns the number of unique pairs that add up to the target number.

[X, Y] and [Y, X] are considered the same pair, and not unique.

Examples

Example 1:

Input: [1, 1, 2, 45, 46, 46], target = 47
Output: 2
Explanation:

1 + 46 = 47

2 + 45 = 47

Example 2:

Input: [1, 1], target = 2
Output: 1
Explanation:

1 + 1 = 2

Example 3:

Input: [1, 5, 1, 5], target = 6
Output: 1
Explanation:

[1, 5] and [5, 1] are considered the same, therefore there is only one unique pair that adds up to 6.

Try it yourself

Solution

Prereq: Two sum

Explanation

Implement a regular solution for the two-sum problem, but use a set to check for and discard duplicates.

Implementation

1def two_sum_unique_pairs(nums: list[int], target: int) -> int:
2    seen = set()
3    complement = set()
4    for num in nums:
5        if target - num in complement:
6            pair = (num, target - num) if num < target - num else (target - num, num)
7            seen.add(pair)
8        complement.add(num)
9    return len(seen)
10
11if __name__ == "__main__":
12    nums = [int(x) for x in input().split()]
13    target = int(input())
14    res = two_sum_unique_pairs(nums, target)
15    print(res)
16
1import java.util.Arrays;
2import java.util.HashSet;
3import java.util.List;
4import java.util.Scanner;
5import java.util.Set;
6import java.util.stream.Collectors;
7
8class Solution {
9    public static int twoSumUniquePairs(List<Integer> nums, int target) {
10        Set<Integer> seen = new HashSet<>();
11        Set<Integer> complement = new HashSet<>();
12        int ans = 0;
13        for (Integer num : nums) {
14            if (complement.contains(target - num) && !seen.contains(num)) {
15                // (num, target - num) is a pair that sums to the target
16                ans++;
17                // mark num and target - num as seen so that when we see (target - num, num) it won't be counted again
18                seen.add(num);
19                seen.add(target - num);
20            }
21            complement.add(num);
22        }
23        return ans;
24    }
25
26    public static List<String> splitWords(String s) {
27        return s.isEmpty() ? List.of() : Arrays.asList(s.split(" "));
28    }
29
30    public static void main(String[] args) {
31        Scanner scanner = new Scanner(System.in);
32        List<Integer> nums = splitWords(scanner.nextLine()).stream().map(Integer::parseInt).collect(Collectors.toList());
33        int target = Integer.parseInt(scanner.nextLine());
34        scanner.close();
35        int res = twoSumUniquePairs(nums, target);
36        System.out.println(res);
37    }
38}
39
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5class Solution
6{
7    public static int TwoSumUniquePairs(List<int> nums, int target)
8    {
9        var seen = new HashSet<(int, int)>();
10        var complement = new HashSet<int>();
11        foreach (int num in nums)
12        {
13            if (complement.Contains(target - num))
14            {
15                var pair = num < target - num ? (num, target - num) : (target - num, num);
16                seen.Add(pair);
17            }
18            complement.Add(num);
19        }
20        return seen.Count;
21    }
22
23    public static List<string> SplitWords(string s)
24    {
25        return string.IsNullOrEmpty(s) ? new List<string>() : s.Trim().Split(' ').ToList();
26    }
27
28    public static void Main()
29    {
30        List<int> nums = SplitWords(Console.ReadLine()).Select(int.Parse).ToList();
31        int target = int.Parse(Console.ReadLine());
32        int res = TwoSumUniquePairs(nums, target);
33        Console.WriteLine(res);
34    }
35}
36
1"use strict";
2
3function twoSumUniquePairs(nums, target) {
4    const seen = new Set();
5    const complement = new Set();
6    for (const num of nums) {
7        if (complement.has(target - num)) {
8            const pair = num < target - num ? `${num},${target - num}` : `${target - num},${num}`;
9            seen.add(pair);
10        }
11        complement.add(num);
12    }
13    return seen.size;
14}
15
16function splitWords(s) {
17    return s === "" ? [] : s.split(" ");
18}
19
20function* main() {
21    const nums = splitWords(yield).map((v) => parseInt(v));
22    const target = parseInt(yield);
23    const res = twoSumUniquePairs(nums, target);
24    console.log(res);
25}
26
27class EOFError extends Error {}
28{
29    const gen = main();
30    const next = (line) => gen.next(line).done && process.exit();
31    let buf = "";
32    next();
33    process.stdin.setEncoding("utf8");
34    process.stdin.on("data", (data) => {
35        const lines = (buf + data).split("\n");
36        buf = lines.pop();
37        lines.forEach(next);
38    });
39    process.stdin.on("end", () => {
40        buf && next(buf);
41        gen.throw(new EOFError());
42    });
43}
44
1function twoSumUniquePairs(nums: number[], target: number): number {
2    const seen = new Set<string>();
3    const complement = new Set<number>();
4    for (const num of nums) {
5        if (complement.has(target - num)) {
6            const pair = num < target - num ? `${num},${target - num}` : `${target - num},${num}`;
7            seen.add(pair);
8        }
9        complement.add(num);
10    }
11    return seen.size;
12}
13
14function splitWords(s: string): string[] {
15    return s === "" ? [] : s.split(" ");
16}
17
18function* main() {
19    const nums = splitWords(yield).map((v) => parseInt(v));
20    const target = parseInt(yield);
21    const res = twoSumUniquePairs(nums, target);
22    console.log(res);
23}
24
25class EOFError extends Error {}
26{
27    const gen = main();
28    const next = (line?: string) => gen.next(line ?? "").done && process.exit();
29    let buf = "";
30    next();
31    process.stdin.setEncoding("utf8");
32    process.stdin.on("data", (data) => {
33        const lines = (buf + data).split("\n");
34        buf = lines.pop() ?? "";
35        lines.forEach(next);
36    });
37    process.stdin.on("end", () => {
38        buf && next(buf);
39        gen.throw(new EOFError());
40    });
41}
42
1#include <algorithm>
2#include <iostream>
3#include <iterator>
4#include <limits>
5#include <set>
6#include <sstream>
7#include <string>
8#include <unordered_set>
9#include <utility>
10#include <vector>
11
12int two_sum_unique_pairs(std::vector<int> nums, int target) {
13    std::set<std::pair<int, int>> seen;
14    std::unordered_set<int> complement;
15    for (int num : nums) {
16        if (complement.count(target - num)) {
17            auto pair = num < target - num
18                ? std::make_pair(num, target - num)
19                : std::make_pair(target - num, num);
20            seen.insert(pair);
21        }
22        complement.insert(num);
23    }
24    return seen.size();
25}
26
27template<typename T>
28std::vector<T> get_words() {
29    std::string line;
30    std::getline(std::cin, line);
31    std::istringstream ss{line};
32    ss >> std::boolalpha;
33    std::vector<T> v;
34    std::copy(std::istream_iterator<T>{ss}, std::istream_iterator<T>{}, std::back_inserter(v));
35    return v;
36}
37
38void ignore_line() {
39    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
40}
41
42int main() {
43    std::vector<int> nums = get_words<int>();
44    int target;
45    std::cin >> target;
46    ignore_line();
47    int res = two_sum_unique_pairs(nums, target);
48    std::cout << res << '\n';
49}
50
1use std::collections::HashSet;
2use std::error;
3use std::io;
4use std::str::FromStr;
5
6fn two_sum_unique_pairs(nums: Vec<i32>, target: i32) -> i32 {
7    let mut seen = HashSet::new();
8    let mut complement = HashSet::new();
9    for num in nums {
10        if complement.contains(&(target - num)) {
11            let pair = if num < target - num {
12                (num, target - num)
13            } else {
14                (target - num, num)
15            };
16            seen.insert(pair);
17        }
18        complement.insert(num);
19    }
20    seen.len() as i32
21}
22
23fn main() -> Result<(), Box<dyn error::Error>> {
24    let mut line = String::new();
25    io::stdin().read_line(&mut line)?;
26    let nums = line
27        .split_whitespace()
28        .map(i32::from_str)
29        .collect::<Result<_, _>>()?;
30    let mut line = String::new();
31    io::stdin().read_line(&mut line)?;
32    let target = line.trim_end().parse()?;
33    let res = two_sum_unique_pairs(nums, target);
34    println!("{}", res);
35    Ok(())
36}
37
1package main
2
3import (
4    "bufio"
5    "fmt"
6    "os"
7    "strconv"
8    "strings"
9)
10
11func twoSumUniquePairs(nums []int, target int) int {
12    type pair struct{ a, b int }
13    seen := make(map[pair]bool)
14    complement := make(map[int]bool)
15    for _, num := range nums {
16        if complement[target-num] {
17            p := pair{num, target - num}
18            if num > target-num {
19                p = pair{target - num, num}
20            }
21            seen[p] = true
22        }
23        complement[num] = true
24    }
25    return len(seen)
26}
27
28func arrayAtoi(arr []string) []int {
29    res := []int{}
30    for _, x := range arr {
31        v, _ := strconv.Atoi(x)
32        res = append(res, v)
33    }
34    return res
35}
36
37func splitWords(s string) []string {
38    if s == "" {
39        return []string{}
40    }
41    return strings.Split(s, " ")
42}
43
44func main() {
45    scanner := bufio.NewScanner(os.Stdin)
46    scanner.Scan()
47    nums := arrayAtoi(splitWords(scanner.Text()))
48    scanner.Scan()
49    target, _ := strconv.Atoi(scanner.Text())
50    res := twoSumUniquePairs(nums, target)
51    fmt.Println(res)
52}
53
1#lang racket
2
3(define (two-sum-unique-pairs nums target)
4  (define-values (seen _)
5    (for/fold ([seen (set)] [complement (set)])
6              ([num (in-list nums)])
7      (if (set-member? complement (- target num))
8          (let ([pair (if (< num (- target num))
9                          (cons num (- target num))
10                          (cons (- target num) num))])
11            (values (set-add seen pair) (set-add complement num)))
12          (values seen (set-add complement num)))))
13  (set-count seen))
14
15(define nums (map string->number (string-split (read-line))))
16(define target (string->number (read-line)))
17(define res (two-sum-unique-pairs nums target))
18(displayln res)
19
1import qualified Data.Set as Set
2
3twoSumUniquePairs :: [Int] -> Int -> Int
4twoSumUniquePairs nums target = Set.size seen
5  where
6    (seen, _) = foldl process (Set.empty, Set.empty) nums
7    process (seenPairs, complement) num
8      | Set.member (target - num) complement =
9          let pair = if num < target - num then (num, target - num) else (target - num, num)
10          in (Set.insert pair seenPairs, Set.insert num complement)
11      | otherwise = (seenPairs, Set.insert num complement)
12
13main :: IO ()
14main = do
15  nums <- map read . words <$> getLine
16  target <- readLn
17  let res = twoSumUniquePairs nums target
18  print res
19
Invest in Yourself
Your new job is waiting. 83% of people that complete the program get a job offer. Unlock unlimited access to all content and features.
Go Pro