Title: Find a Pair with the Given Product
In this guide, you’ll learn how to find a pair of numbers in an array whose product equals a given target value. This is a classic array interview question that tests whether you can adapt the familiar hash-set lookup trick from the two-sum problem to multiplication instead of addition.
We’ll walk through a clean O(n) time approach using a HashSet, trace it by hand on a tricky input, and then cover the mistakes, edge cases, and follow-up questions an interviewer is likely to raise.
Understanding the Problem
Given an integer array nums and an integer targetProduct, the task is to find two elements in the array whose product equals targetProduct. If such a pair exists, report the two values; otherwise report that no pair was found.
Negative numbers and zero are both valid elements, and both require careful handling once the pair is built from a product rather than a sum. A value can only pair with itself if it genuinely appears twice in the array, not once.
Approach to Solve the Problem
- Create an empty
HashSet<Integer>namedseento record every number processed so far. - Iterate over the array
numsone element at a time, calling the current valuecurrent. - If
currentis0, check whethertargetProductis also0and whetherseenalready contains a zero; if so, a pair of zeros has been found. - Otherwise, when
currentis0and no pair is found yet, add0toseenand move on, since dividing by zero must never be attempted. - For a nonzero
current, test whethertargetProduct % current == 0so the complement is a whole number rather than a fraction. - When it divides evenly, compute
complement = targetProduct / currentand check whethercomplementis already present inseen. - If
complementis found, return the pair(complement, current)immediately, since no later element needs to be examined. - Otherwise add
currenttoseenand continue scanning; if the loop finishes without a match, return an empty result.
Java Program to Find a Pair with the Given Product
import java.util.HashSet;
import java.util.Set;
public class FindPairWithGivenProduct {
public static int[] findPairWithProduct(int[] nums, int targetProduct) {
Set<Integer> seen = new HashSet<>();
for (int current : nums) {
if (current == 0) {
if (targetProduct == 0 && seen.contains(0)) {
return new int[] {0, 0};
}
seen.add(0);
continue;
}
if (targetProduct % current == 0) {
int complement = targetProduct / current;
if (seen.contains(complement)) {
return new int[] {complement, current};
}
}
seen.add(current);
}
return new int[0];
}
public static void main(String[] args) {
int[] nums = {10, 4, 8, 60, 20, 5};
int targetProduct = 40;
int[] result = findPairWithProduct(nums, targetProduct);
if (result.length == 2) {
System.out.println("Pair found: " + result[0] + " x " + result[1] + " = " + targetProduct);
} else {
System.out.println("No pair found with product " + targetProduct);
}
}
}Explanation of the Program
The method findPairWithProduct scans nums once, using a HashSet<Integer> called seen to remember every value visited so far.
current == 0is handled first and separately, because dividing by zero would throw anArithmeticException. A pair is only reported when a second zero shows up after the first.- For any other value,
targetProduct % current == 0confirms the division produces a whole number beforetargetProduct / currentis trusted as the complement. - The complement is checked against
seenbeforecurrentitself is added toseen, which stops an element from being paired with itself unless it genuinely appears twice in the array. - The method returns as soon as a match is found, so
numsis never scanned further than necessary.
Step-by-Step Trace
Trace findPairWithProduct on nums = {7, 0, -3, 4, 0, -4} with targetProduct = -12. The method returns the pair (-3, 4) after four iterations.
| Iteration | current | seen (before) | complement check | seen (after) |
|---|---|---|---|---|
| 1 | 7 | { } | -12 % 7 != 0, not divisible | {7} |
| 2 | 0 | {7} | zero, but targetProduct != 0 | {7, 0} |
| 3 | -3 | {7, 0} | complement = 4, not in seen | {7, 0, -3} |
| 4 | 4 | {7, 0, -3} | complement = -3, found in seen | pair (-3, 4) returned |
At the end of each iteration, seen holds every element processed before the current one, so testing complement against seen can only ever match an element that appeared earlier in the array, which is exactly what keeps an index from pairing with itself.
Examples
Example 1: A Straightforward Pair
With nums = {10, 4, 8, 60, 20, 5} and targetProduct = 40, the method finds 10 and 4 as soon as 4 is reached, since 10 is already in seen.
int[] nums = {10, 4, 8, 60, 20, 5};
int targetProduct = 40;
int[] result = findPairWithProduct(nums, targetProduct);
// Output: Pair found: 10 x 4 = 40Example 2: No Pair Exists
With nums = {1, 2, 3, 9, 8} and targetProduct = 100, no two elements multiply to 100, so the method scans the entire array and returns an empty result.
int[] nums = {1, 2, 3, 9, 8};
int targetProduct = 100;
int[] result = findPairWithProduct(nums, targetProduct);
// Output: No pair found with product 100Example 3: A Pair of Zeros
With nums = {4, 7, 0, 0} and targetProduct = 0, the first 0 is only recorded in seen; the second 0 triggers the zero-pair check and the method returns (0, 0).
int[] nums = {4, 7, 0, 0};
int targetProduct = 0;
int[] result = findPairWithProduct(nums, targetProduct);
// Output: Pair found: 0 x 0 = 0Common Mistakes to Avoid
These are the slip-ups that actually show up when candidates solve this problem, not generic advice.
- Computing targetProduct % current before checking for zero – dividing or taking the modulus of
current == 0throws anArithmeticException. Always branch on zero first. - Adding current to seen before checking its complement – this lets a single occurrence of a value satisfy itself, wrongly reporting a pair like
(6, 6)when6appears only once. Checkseenfirst, then add. - Reporting a zero pair after seeing only one zero – returning as soon as the first
0is read falsely claims a pair exists even when the array has a single zero. Require a second zero before returning. - Trusting targetProduct / current without checking the remainder – integer division truncates, so
complementcan be wrong whenevercurrentdoes not evenly dividetargetProduct. Guard every division withtargetProduct % current == 0. - Printing nums[i] * nums[j] directly for verification – multiplying two large
intvalues can silently overflow. Cast tolongbefore multiplying if the inputs might be large.
Edge Cases to Test
Walk through these inputs before calling the solution finished.
- Empty array
- Single-element array
- No pair produces the target product
- Duplicate values that form the pair (e.g. target is a perfect square)
- Array containing exactly one zero with targetProduct equal to zero
- Array containing two or more zeros with targetProduct equal to zero
- Negative targetProduct with mixed-sign elements
- Integer.MIN_VALUE or Integer.MAX_VALUE present, where division or multiplication could overflow
Additional Considerations
The hash-set approach runs in O(n) time and uses O(n) extra space, since each element is visited once and at most all of them end up stored in seen.
If the array is already sorted, or mutation is allowed, a two-pointer sweep can solve the same problem in O(n log n) time (for the sort) but only O(1) extra space, trading memory for the sorting cost.
Division and modulus on int values never overflow the way multiplication can, so checking targetProduct % current is safe even for large inputs; only an explicit multiplication done for verification needs a long cast.
Interview Follow-up Questions
An interviewer rarely stops at the base case. Expect questions like these once the first solution works.
- What if you need every pair with the given product, not just the first one? – group values by frequency in a map first, then for each distinct value compute its complement and combine the counts, taking care not to double count a value paired with itself.
- What if the array is sorted and contains only non-negative numbers? – use two pointers starting at both ends, moving the left pointer right when the product is too small and the right pointer left when it is too large, for
O(n)time andO(1)extra space. - What if the input arrives as a stream of unknown length? – keep the same
HashSetand check each new value against it as it arrives; termination comes from the end of the stream rather than the array length. - What if you cannot use any extra memory beyond the input array? – sort the array in place and apply the two-pointer technique, accepting
O(n log n)time in exchange for dropping theHashSet. - What if no exact pair exists and you need the product closest to the target instead? – sort the array, sweep with two pointers, and track the smallest absolute difference between the running product and the target seen so far.
Conclusion
Finding a pair with a given product is a small twist on the classic hash-set lookup pattern, but zero and negative values force you to handle division carefully instead of reaching for it blindly. Once the zero case and the divisibility check are in place, the rest of the logic is a single clean pass over the array.
Try adapting findPairWithProduct to return every matching pair, or to work on a sorted array with two pointers, to make sure the idea has fully sunk in. You can learn more about array-based interview problems in the Arrays category on this site.



