Намерете всички двойки числа в масив, който добавя към дадена сума в Java

1. Общ преглед

В този бърз урок ще покажем как да внедрите алгоритъм за намиране на всички двойки числа в масив, чиято сума е равна на дадено число. Ще се спрем на два подхода към проблема .

При първия подход ще открием всички такива двойки, независимо от уникалността. Във втория ще открием само уникалните комбинации от числа, премахвайки излишните двойки.

За всеки подход ще представим две реализации - традиционна реализация, използваща for контури, и втора, използваща Java 8 Stream API.

2. Върнете всички съвпадащи двойки

Ще повторим през масив от цели числа, като намерим всички двойки ( i и j ), които се сумират до дадения номер ( сума ), използвайки груба сила, вложен цикъл. Този алгоритъм ще има сложност на изпълнение по време на O (n2) .

За нашите демонстрации ще потърсим всички двойки числа, чиято сума е равна на 6 , като използваме следния входен масив:

int[] input = { 2, 4, 3, 3 }; 

При този подход нашият алгоритъм трябва да върне:

{2,4}, {4,2}, {3,3}, {3,3}

Във всеки от алгоритмите, когато намерим целева двойка числа, които обобщават целевото число, ще съберем двойката с помощта на полезен метод addPairs (i, j) .

Първият начин, по който можем да помислим да приложим решението, е да използваме традиционния for цикъл:

for (int i = 0; i < input.length; i++) { for (int j = 0; j < input.length; j++) { if (j != i && (input[i] + input[j]) == sum) { addPairs(input[i], sum-input[i])); } } }

Това може да е малко елементарно, така че нека също напишем реализация, използвайки Java 8 Stream API .

Тук използваме метода IntStream.range, за да генерираме последователен поток от числа. След това ги филтрираме за нашето състояние: номер 1 + номер 2 = сума :

IntStream.range(0, input.length) .forEach(i -> IntStream.range(0, input.length) .filter(j -> i != j && input[i] + input[j] == sum) .forEach(j -> addPairs(input[i], input[j])) ); 

3. Върнете всички уникални съвпадащи двойки

За този пример ще трябва да разработим по-интелигентен алгоритъм, който връща само уникалните комбинации от числа, като пропуска излишните двойки .

За да постигнем това, ще добавим всеки елемент към хеш карта (без сортиране), като първо проверяваме дали двойката вече е показана. Ако не, ще го извлечем и маркираме както е показано (задайте полето за стойност като null ).

Съответно, използвайки същия входен масив, както преди, и целева сума от 6 , нашият алгоритъм трябва да върне само различните комбинации от числа:

{2,4}, {3,3}

Ако използваме традиционен цикъл for , ще имаме:

Map pairs = new HashMap(); for (int i : input) { if (pairs.containsKey(i)) { if (pairs.get(i) != null) { addPairs(i, sum-i); } pairs.put(sum - i, null); } else if (!pairs.containsValue(i)) { pairs.put(sum-i, i); } }

Имайте предвид, че тази реализация подобрява предишната сложност, тъй като използваме само една за цикъл, така че ще имаме O (n) .

Сега нека решим проблема с помощта на Java 8 и Stream API:

Map pairs = new HashMap(); IntStream.range(0, input.length).forEach(i -> { if (pairs.containsKey(input[i])) { if (pairs.get(input[i]) != null) { addPairs(input[i], sum - input[i]); } pairs.put(sum - input[i], null); } else if (!pairs.containsValue(input[i])) { pairs.put(sum - input[i], input[i]); } });

4. Заключение

В тази статия обяснихме няколко различни начина за намиране на всички двойки, които обобщават дадено число в Java. Видяхме две различни решения, всяко от които използва два основни метода на Java.

Както обикновено, всички примерни кодове, показани в тази статия, могат да бъдат намерени в GitHub - това е проект на Maven, така че трябва да е лесно да се компилира и стартира.