Created
November 21, 2015 23:37
-
-
Save sabotuer99/173efa3c16b247a3b556 to your computer and use it in GitHub Desktop.
FIND-MAX-SUBARRAY from CLRS in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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