Skip to main content

Three sum problem using hash map in java

Given an array and a value, find all the triplets in the array whose sum is equal to the given value. For example, if the given array is {12, 3, 4, 1, 6, 9} and the given sum is 24, then this is one triplet (12, 3 and 9) which contributes to the total sum of 24.

Solution for given example:

6, 9, 9

6, 6, 12

3, 9, 12

Conditions:

  • The ordering of the numbers in the solution does not matter.

  • Duplicate triplet is not allowed.

  • A number is not allowed to be used multiple times.

This question was asked in Find all triplets in array that add up to a given sum

Here is my code which addresses all the issues.

One concern is the code looks a little muddy which I want to avoid in the production grade code. Any constructive feedback is appreciated.

public class ThreeSum {

    static class Triplet {
        final List<Integer> triplets;

        public Triplet(int x, int y, int z) {
            triplets = Arrays.asList(x, y, z);
            Collections.sort(triplets);
        }

        @Override
        public int hashCode() {
            return Objects.hash(triplets.get(0), triplets.get(1), triplets.get(2));
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof Triplet) {

                Triplet other = (Triplet) o;
                return other.triplets.get(0) == this.triplets.get(0) &&
                        other.triplets.get(1) == this.triplets.get(1) &&
                        other.triplets.get(2) == this.triplets.get(2);
            }

            return false;
        }

        @Override
        public String toString() {
            return String.format("(%d, %d, %d)", triplets.get(0), triplets.get(1), triplets.get(2));
        }
    }

    public static Set<Triplet> findTriplets(int numbers[], int targetSum) {
        Set<Triplet> triplets = new HashSet<>();

        // insert all pairs in the look up table
        Map<Integer, int[]> lookup = new HashMap<>();
        for (int i = 0; i < numbers.length - 1; i++) {
            for (int j = i + 1; j < numbers.length; j++) {
                int total = numbers[i] + numbers[j];
                lookup.put(total, new int[]{i, j});
            }
        }

        // look for the complement, if found viola! here you go with the triplet
        for (int currentIndex = 0; currentIndex < numbers.length; currentIndex++) {
            int complement = targetSum - numbers[currentIndex];

            if (lookup.containsKey(complement)) {
                int indexes[] = lookup.get(complement);

                if (currentIndex != indexes[0] && currentIndex != indexes[1]) {
                    int x = numbers[indexes[0]], y = numbers[indexes[1]];
                    triplets.add(new Triplet(x, y, numbers[currentIndex]));
                }
            }
        }

        return triplets;
    }
}

Github Link: https://github.com/Ramblers-Code/CodeKata/blob/master/src/main/java/kata/array/ThreeSum.java#L5

Exploring
  • 345
  • 4
  • 19