2

I am just trying to look through an array and find the elements that sum up to the target number. I've gotten this far into the program:

public class App {
    public static void main(String[] args) throws Exception {
        int[] numbers = {3, 6, 2, 9};
        int targNum = 5;

        twoSum(numbers, targNum);
    }

    public static void twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            int sum = 0;

            if (nums[i] <= target) {
                int[] sumNums = {target - nums[i]};

                for (int j = 0; j < sumNums.length; j++) {
                    sum += sumNums[j];
                    System.out.println(sum);
                }
            }
        }
    }
}

I keep getting console output of:

2
3

I ran a simple array sum in another file and it seemed to work perfectly.

jpenn2472
  • 21
  • 2

2 Answers2

2

You should use Set to look through the given array only once.

public class App {

    public static void main(String[] args) throws Exception {
        int[] numbers = { 3, 6, 2, 9 };
        int targNum = 5;

        twoSum(numbers, targNum);
    }

    public static void twoSum(int[] nums, int target) {
        Set<Integer> unique = new HashSet<>();

        for (int a : nums) {
            int b = target - a;

            if (unique.contains(b)) {
                System.out.println(a + " " + b);
                return;
            }

            unique.add(a);
        }

        System.err.println("not found");

    }

}
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
  • 1
    Awesome answer! Didn't think about using a set to avoid duplicates, which was the next problem I was going to run into. Thanks! – jpenn2472 Mar 04 '21 at 18:19
  • @jpenn2472 You should accept the answer if helps resolve the issue. – WJS Mar 04 '21 at 18:40
0

You can use IntStream instead of for-loop:

int[] numbers = {3, 6, 2, 9};
int targetSum = 5;
// Map.Entry<Set<Integer>,Integer>
var entry = IntStream
        // iterating through the array indexes
        .range(0, numbers.length)
        // map each index as a pair of index and value,
        // i.e. set of indexes and sum of values
        // Stream<Map.Entry<Set<Integer>,Integer>>
        .mapToObj(i -> Map.entry(Set.of(i), numbers[i]))
        // reduce stream of map entries to a single entry
        .reduce((e1, e2) -> {
            int sum = e1.getValue() + e2.getValue();
            // if sum of the values of the two entries
            // is less than or equal to the target sum
            if (sum <= targetSum) {
                // summarize two entries
                Set<Integer> key = new HashSet<>();
                key.addAll(e1.getKey());
                key.addAll(e2.getKey());
                return Map.entry(key, sum);
            } else {
                // otherwise, take an entry with a smaller sum
                return e1.getValue() < e2.getValue() ? e1 : e2;
            }
        }).orElse(null);
// output
if (entry == null)
    System.out.println("Not found");
else
    entry.getKey().forEach(i -> System.out.println(numbers[i]));

Output:

3
2

See also: How to sort a character by number of occurrences in a String using a Map?