Skip to content

Instantly share code, notes, and snippets.

@sabotuer99
Created November 21, 2015 23:37
Show Gist options
  • Save sabotuer99/173efa3c16b247a3b556 to your computer and use it in GitHub Desktop.
Save sabotuer99/173efa3c16b247a3b556 to your computer and use it in GitHub Desktop.
FIND-MAX-SUBARRAY from CLRS in Java
//I was trying to do a Modulo sum, but this approach didn't work.
//I tried to take all the mod stuff out (I'm pretty sure it's a decent
//implementation of max subarray) but I may have missed something...
public static void log(Object message){
System.out.println(message);
}
/* CLRS pg.71
FIND-MAX-CROSSING-SUBARRAY(A, low, mid, high)
left-sum = -INF
sum = 0
for i = mid downto low
sum = sum + A[i]
if sum > left-sum
left-sum = sum
max-left = i
right-sum = -INF
sum = 0
for j = mid + 1 to high
sum = sum + A[j]
if sum > right-sum
right-sum = sum
max-right = j
return (max-left, max-right, left-sum + right-sum)
*/
public static int[] FIND_MAX_CROSSING_SUBARRAY(int[] A, int low, int mid, int high){
//Compute left max subarray
int leftsum = Integer.MIN_VALUE;
int maxleft = mid;
int sum = 0;
for(int i = mid; i >= low; i--){
sum = sum + A[i];
if(sum > leftsum){
leftsum = sum;
maxleft = i;
}
}
//Compute right max subarray
int rightsum = Integer.MIN_VALUE;
int maxright = mid + 1;
sum = 0;
for(int j = mid + 1; j <= high; j++){
sum = sum + A[j];
if(sum > rightsum){
rightsum = sum;
maxright = j;
}
}
int[] result = { maxleft, maxright, leftsum + rightsum};
return result;
}
/* CLRS pg.72
FIND-MAXIMUM-SUBARRAY(A, low, high)
if high == low
return (low, high, A[low]) //base case, only one element
else mid = FLOOR((low + high)/2)
(left-low, left-high, left-sum) =
FIND-MAXIMUM-SUBARRAY(A, low, mid)
(right-low, right-high, right-sum) =
FIND-MAXIMUM-SUBARRAY(A, mid + 1, high)
(cross-low, cross-high, cross-sum) =
FIND-MAXIMUM-CROSSING-SUBARRAY(A, low, mid, high)
if left-sum >= right-sum and left-sum >= cross-sum
return (left-low, left-high, left-sum)
elseif right-sum >= left-sum and right-sum >= cross-sum
return (right-low, right-high, right-sum)
else return (cross-low, cross-high, cross-sum)
*/
public static int counter = 0;
public static int[] FIND_MAXIMUM_SUBARRAY(int[] A, int low, int high){
//debugging
String padding = "";
for(int i = 0; i < counter; i++)
padding += " ";
counter++;
if(high == low){
int[] result = {low, high, A[low]};
return result;
} else {
int mid = (low + high)/2;
log(padding + "Left: " + low + " " + mid);
int[] left = FIND_MAXIMUM_SUBARRAY(A, low, mid);
log(padding + "Right: " + (mid + 1) + " " + high);
int[] right = FIND_MAXIMUM_SUBARRAY(A, mid + 1, high);
log(padding + "Cross: " + low + " " + mid + " " + high);
int[] cross = FIND_MAX_CROSSING_SUBARRAY(A, low, mid, high);
if(left[2] >= right[2] && left[2] >= cross[2]){
log(padding + "Returned left...");
return left;
}
else if(right[2] >= left[2] && right[2] >= cross[2]){
log(padding + "Returned right...");
return right;
}
else {
log(padding + "Returned cross...");
return cross;
}
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for(; t > 0; t--){
int N = in.nextInt();
int M = in.nextInt();
int[] A = new int[N];
for(int i = 0; i < N; i++)
A[i] = in.nextInt();
System.out.println(FIND_MAXIMUM_SUBARRAY(A, 0, N-1)[2]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment