Подскажите, есть массив, необходимо вывести два элемента, которые в сумме дают 10. Каким будет решение через stream?
int[] arr = {3, 4, 2, 7};
int x = 10;
for (int i = 0; i<arr.length; i++) {
for(int j = i + 1; j<arr.length; j++){
if(arr[i] + arr[j] == x){
System.out.println(arr[i] + " " + arr[j]);
}
}
}
Ответы (1 шт):
Автор решения: Nowhere Man
→ Ссылка
Подобно решению с циклами следует сгенерировать целочисленный поток для индекса i, из которого можно будет сгенерировать поток для индекса j и соответственно отфильтровать пары индексов, отвечающих условию, затем применить flatMap и findFirst/findAny для получения результата в виде Optional<int[]>.
int[] arr = {3, 4, 2, 7};
int x = 10;
IntStream.range(0, arr.length - 1)
.mapToObj(i -> IntStream.range(i + 1, arr.length)
.filter(j -> arr[i] + arr[j] == x)
.mapToObj(j -> new int[]{i, j}) // Stream<int[]>
) // Stream<Stream<int[]>>
.flatMap(str -> str) // Stream<int[]>
.findFirst() // Optional<int[]>
.ifPresentOrElse(
ix -> System.out.println(arr[ix[0]] + " + " + arr[ix[1]] + " == " + x),
() -> System.out.println("NOT FOUND")
);
// -> 3 + 7 == 10
Однако оба представленных решения имеют квадратичную сложность,тогда как её можно упростить до O(N), правда без стримов и с использованием мапы, как показано в ответе на похожий вопрос:
public static int[] twoSum(final int target, int ... nums) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0, n = nums.length; i < n; i++) {
int a = nums[i];
int b = target - a;
if (map.containsKey(b)) {
return new int[]{map.get(b), i};
}
map.put(a, i); // запомнить меньший индекс
}
throw new RuntimeException("the pair is not found");
}