public class GrassPasture {
private int[][] pastures;
public GrassPasture(int[][] pastures) {
this.pastures = pastures;
}
public int getTotalGrass() {
int sum = 0;
for (int[] row : pastures) {
for (int i : row) {
sum += i;
}
}
return sum;
}
public int maxSquare() {
int[][] sumArray = new int[pastures.length][pastures[0].length]; // sum array from [0][0] to [i][j]
for (int i = 0; i < pastures.length; i++) { // create the sum array
for (int j = 0; j < pastures[0].length; j++) {
sumArray[i][j] = pastures[i][j]; // add the index
if (i != 0) {
sumArray[i][j] += sumArray[i - 1][j]; // add the top neighbor if it exists
}
if (j != 0) {
sumArray[i][j] += sumArray[i][j - 1]; // add the right neighbor if it exists
}
if (i != 0 && j != 0) {
sumArray[i][j] += sumArray[i - 1][j - 1]; // add the top right neighbor if it exists
}
}
}
int max = Integer.MIN_VALUE; // initial max is lowest integer value
int sum; // to save sum values
for (int n = 1; n <= Integer.min(pastures.length, pastures[0].length); n++) { // for every size square of n x n
for (int i = 0; i < pastures.length - n + 1; i++) {
for (int j = 0; j < pastures[0].length - n + 1; j++) {
sum = sumArray[n + i - 1][n + j - 1]; // add the sum from [0][0] to [i][j]
if (i != 0) {
sum -= sumArray[i - 1][n + j - 1]; // subtract the sums outside the square
}
if (j != 0) {
sum -= sumArray[n + i - 1][j - 1];
}
if (i != 0 && j != 0) {
sum -= sumArray[i - 1][j - 1];
}
max = Integer.max(max, sum); // keep sum if higher than max
}
}
}
return max; // return max
}
public int maxSubarraySum() {
int[] flat = new int[pastures.length * pastures[0].length]; // create new flat array of size of number of total elements in pastures
for (int i = 0; i < pastures.length; i++) { // copy each array into flat
System.arraycopy(pastures[i], 0, flat, i * pastures.length, pastures[0].length);
}
// kadane's algorithm
int max = Integer.MIN_VALUE;
int sum = 0;
for (int i : flat) {
sum = Integer.max(i, sum + i);
max = Integer.max(max, sum);
}
return max;
}
public static void main(String[] args) {
int[][] pastures = {
{-3, 6, -1},
{2, -1, 5},
{-9, 4, -1}
};
GrassPasture gp = new GrassPasture(pastures);
System.out.println("Total Tastiness: " + gp.getTotalGrass());
System.out.println("Max Square Sum: " + gp.maxSquare());
System.out.println("Max Subarray Sum: " + gp.maxSubarraySum());
/* Extra credit
* 1. my time complexity for maxSquare() is O(pastures.length * pastures[0].length * Integer.min(pastures.length, pastures[0].length)).
* it uses a triple nested for loop looking from 1 to n (minimum of x and y length), 1 to i (x length), and 1 to j (y length).
* 3. my time complexity for maxSubarraySum() is O(pastures.length * pastures[0].length).
* it uses a kadane's algorithm which is O(n*m) and flattening the array is also O(n*m)
*/
}
}