public class MaxSubarray {
class Stats {
int max;
int sum;
int count;
Stats(int max, int sum, int count) {
this.max = max;
this.sum = sum;
this.count = count;
}
@Override
public String
toString() {
return String.format("Max: %d, Sum: %d, Count: %d, Avg: %.2f",
max, sum, count, (double)sum/count);
}
}
public void combineUsingStats() {
int[][] arrays = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Stats stats = Arrays.stream(arrays)
.collect(
//
Supplier: Create initial Stats object
()
-> new Stats(Integer.MIN_VALUE, 0, 0),
//
Accumulator: Process each array
(state, array) -> {
for
(int num :
array) {
state.max = Math.max(state.max, num);
state.sum += num;
state.count++;
}
},
//
Combiner: Merge two Stats objects
(state1, state2) -> {
state1.max = Math.max(state1.max, state2.max);
state1.sum += state2.sum;
state1.count += state2.count;
}
);
System.out.println(stats); // Max: 9, Sum: 45, Count: 9, Avg: 5.00
}
public static void combineArraysIntoMap() {
String[] arr1 = {"apple", "banana", "orange"};
String[] arr2 = {"grape", "kiwi",
"mango"};
String[] arr3 = {"peach", "plum",
"pear"};
// Combine
arrays with their original array index
Map<Integer, List<String>> result =
Stream.of(arr1, arr2, arr3)
.collect(
//
Supplier: Create HashMap
HashMap::new,
//
Accumulator: Add array elements to map
(map, array) -> {
int
index = map.size(); //
Current array index
map.put(index, Arrays.asList(array));
},
//
Combiner: Merge two maps
(map1, map2) -> map1.putAll(map2)
);
result.forEach((index, list) ->
System.out.println("Array
" + index + ":
" + list));
}
public static void combine3Arrays2() {
int[] arr1 = {1, 2, 3};
int[] arr2 = {4, 5, 6};
int[] arr3 = {7, 8, 9};
// Combine three
arrays using collect()
int[] result = Stream.of(arr1, arr2, arr3)
.collect(
//
Supplier: Create initial ArrayList
ArrayList<Integer>::new,
//
Accumulator: Add each array's elements to the list
(list, array) -> {
for
(int num :
array) {
list.add(num);
}
},
//
Combiner: Merge two lists (for parallel streams)
(list1, list2) -> list1.addAll(list2)
)
.stream()
.mapToInt(Integer::intValue)
.toArray();
System.out.println(Arrays.toString(result)); //
[1, 2, 3, 4, 5, 6, 7, 8, 9]
}
public static void combine3Arrays() {
int[][] arrays = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Combine and
find max from all arrays
int[] result = Arrays.stream(arrays)
.collect(
//
Supplier: Create array [max, sum, count]
()
-> new int[]{Integer.MIN_VALUE, 0, 0},
//
Accumulator: Process each array
(state, array) -> {
for
(int num :
array) {
state[0] = Math.max(state[0], num); // max
state[1] += num; // sum
state[2]++; // count
}
},
//
Combiner: Merge two states
(state1, state2) -> {
state1[0] = Math.max(state1[0], state2[0]); // max of maxes
state1[1] += state2[1];
// sum of sums
state1[2] += state2[2];
// count of counts
}
);
System.out.println("Max:
" + result[0]); // 9
System.out.println("Sum:
" + result[1]); // 45
System.out.println("Count:
" + result[2]); // 9
}
public static int maxSubarray(int[] arr) {
System.out.println("
Question " + Arrays.toString(arr));
// Create an
array to hold [max, sum] as mutable state
int[] result = Arrays.stream(arr).collect(
() -> new int[]{arr[0], 0}, // [max, sum]
(state, num) -> {
state[1] += num;
state[0] = Math.max(state[0], state[1]);
if (state[1] < 0) state[1] = 0;
},
(state1, state2) -> {
//
Not needed for sequential streams
}
);
return result[0];
}
public static int maxSubarray2(int[] arr) {
System.out.println("
Question " + Arrays.toString(arr));
// Using
AtomicInteger to maintain state
AtomicInteger sum = new AtomicInteger(0);
AtomicInteger max = new AtomicInteger(arr[0]);
Arrays.stream(arr).forEach(num -> {
sum.addAndGet(num);
max.set(Math.max(max.get(), sum.get()));
if (sum.get() < 0) sum.set(0);
});
return max.get();
}
public static int maxSubarray1(int[] arr) {
System.out.println("
Question " + Arrays.toString(arr));
int max = arr[0], sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
max = Math.max(max, sum);
System.out.println(
"
c : " + arr[i] +
",
sum : " + sum +
",
max : " + max
);
if(sum < 0) sum = 0;
}
return max;
}
public static void main (String[] args) {
System.out.println("1)"
+ maxSubarray(new int[]{-2, 5, -1, 7, -3}) + " = 11");
System.out.println("2)"
+ maxSubarray(new int[]{1, -2, 0, 3}) + "
= 3");
System.out.println("3)"
+ maxSubarray(new int[]{3, -1, -1, 4, 3, -1}) + " = 8");
System.out.println("4)"
+ maxSubarray(new int[]{1,1,1,1}) + "
= 4");
System.out.println("5)"
+ maxSubarray(new int[]{-4, -5, -6}) + " = -4");
System.out.println("6)"
+ maxSubarray(new int[]{10, -2}) + " = 10");
System.out.println("7)"
+ maxSubarray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4}) + " = 6");
System.out.println("8)"
+ maxSubarray(new int[]{-2,1,-3,4,-1,2,1,-5,4}) + " = 6");
System.out.println("9)"
+ maxSubarray(new int[]{-1,1,-1,1,-1}) + " = 1");
System.out.println("10)"
+ maxSubarray(new int[]{-4, 2, 3, -5, 1, 2, -4, 2}) + " = 5");
}
}