Maxsub array using divide and conquer - java

I am having trouble implementing max sub array problem using divide and conquer.
Lets say I have an array [3,6,-1,2] and I want to find the max sum of this array in contiguous order. We can look at this and see that the sum is 10 from [0,3].
I tried implementing the pseudo code from my book but the answer is not correct.
// return (max-left, max-right, max sum left + right)
public static int[] maxcross(int[] array, int low, int mid, int high) {
int leftSum = -10000000;
int rightSum = -10000000;
int sum = 0;
int maxLeft=0;
int maxRight=0;
for(int i=mid;i<mid-low;i--){
sum = sum + array[i];
if(leftSum < sum){
leftSum = sum;
maxLeft = i;
}
}
sum=0;
for(int i=mid+1;i<high;i++){
sum = sum + array[i];
if(rightSum < sum){
rightSum = sum;
maxRight = i;
}
}
int cross[] = {maxLeft,maxRight,leftSum+rightSum};
return cross;
}
public static int[] maxsub(int array[], int low, int high){
int[] maxSubLeft = new int[3];
int[] maxSubRight = new int[3];
int[] maxSub = new int[3];
int[] maxSubCross = new int[3];
int mid;
if (high==low){
maxSub[0] = low;
maxSub[1] = high;
maxSub[2] = array[low];
return maxSub;
}
else{
mid = (int) Math.floor((low+high)/2);
maxSubLeft = maxsub(array,low,mid);
maxSubRight = maxsub(array,mid+1,high);
maxSubCross = maxcross(array,low,mid,high);
if(maxSubLeft[2] >= maxSubRight[2] && maxSubLeft[2] >= maxSubCross[2])
return maxSubLeft;
else if(maxSubRight[2] >= maxSubLeft[2] && maxSubRight[2] >= maxSubCross[2])
return maxSubRight;
else
return maxSubCross;
}
}
I am getting this as the output
1
1
6
Can someone help me?

The recursive initial output is wrong in maxsub(...), return 0 when high=low and array[low] < 0;
public static int[] maxsub(int array[], int low, int high){
int[] maxSubLeft = new int[3];
int[] maxSubRight = new int[3];
int[] maxSub = new int[3];
int[] maxSubCross = new int[3];
int mid;
if (high==low){
maxSub[0] = low;
maxSub[1] = high;
maxSub[2] = array[low];
return maxSub; // if (array[low] < 0) return 0;
}
else{
mid = (int) Math.floor((low+high)/2);
maxSubLeft = maxsub(array,low,mid);
maxSubRight = maxsub(array,mid+1,high);
maxSubCross = maxcross(array,low,mid,high);
if(maxSubLeft[2] >= maxSubRight[2] && maxSubLeft[2] >= maxSubCross[2])
return maxSubLeft;
else if(maxSubRight[2] >= maxSubLeft[2] && maxSubRight[2] >= maxSubCross[2])
return maxSubRight;
else
return maxSubCross;
}
}
By the way, your recursive algorithm is O(NlnN), a more effective and easy to implement algorithm is O(N), which applies the dynamic programming.
public static int maxSum(int array[], int low, int high) {
int maxsum = 0, maxleftsum = 0;
for (int i = low; i < high; i++) {
maxsum = max(maxsum, array[i] + maxleftSum);
maxleftSum = max(0, maxleftSum+array[i]);
}
return maxsum; // return the index if necessary.
}

Related

Quickselect that runs in O(n) in Java?

So I'm implement a quickselect algorithm that chooses a good pivot each time. What it does is divide the array into groups of 5, sorts each groups and finds the median. It then takes the medians of each group, groups those values up and then finds the median of medians. Here's what I have:
private static int pickCleverPivot(int left, int right, int[] A){
int index = 0;
int n = right-left;
if (n <= 5) {
Arrays.sort(A);
index = n/2;
return index;
}
int numofMedians = (int) Math.ceil(n/5);
int[] medians = new int[numofMedians];
int[] groups = new int[5];
for(int i = 0; i < numofMedians; i++) {
if (i != numofMedians - 1){
for (int j = 0; j < 5; j++){
groups[j] = A[(i*5)+j];
}
medians[i] = findMedian(groups, 5);
} else {
int numOfRemainders = n % 5;
int[] remainder = new int[numOfRemainders];
for (int j = 0; j < numOfRemainders; j++){
remainder[j] = A[(i*5)+j];
}
medians[i] = findMedian(groups, 5);
}
}
return pickCleverPivot(left, left+(numofMedians), medians);
}
public static int findMedian(int[] A, int n){
Arrays.sort(A);
if (n % 2 == 0) {
return (A[n/2] + A[n/2 - 1]) / 2;
}
return A[n/2];
}
private static int partition(int left, int right, int[] array, int pIndex){
//move pivot to last index of the array
swap(array,pIndex,right);
int p=array[right];
int l=left;
int r=right-1;
while(l<=r){
while(l<=r && array[l]<=p){
l++;
}
while(l<=r && array[r]>=p){
r--;
}
if (l<r){
swap(array,l,r);
}
}
swap(array,l,right);
return l;
}
private static void swap(int[]array, int a, int b){
int tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
So it works like it's supposed to but now I'm wondering if it's possible to get it to run in linear O(n) time. I'm currently comparing this code to just choosing a random pivot. On smaller arrays this code runs faster but on larger arrays, choosing a random pivot is faster. So is it actually possible to make this run in O(n) time or is that just in theory and if it's not possible for it to run that fast then is this method running as fast as it could.

My program seems to be written perfectly, but stops running and allows user input with no scanner?

first time post here.
I am trying to create a class which compares quick sort, merge sort, bubble sort, and selection sort. I have implemented all of the sort methods and created a random array method which populates a random array with 1000 random ints. However when I run my program my main method stops after the initial welcome message and allows for user input. Any help would be greatly appreciated, I'm sure its some simple mistake I am missing.
import java.util.Random;
public class TestSort {
private static int selectCount;
private static int bubbleCount;
private static int mergeCount;
private static int quickCount;
public static void main(String[] args){
System.out.println("Welcome to the search tester. "
+ "We are going to see which algorithm performs the best out of 20 tests");
int testSelection = 0;
int testBubble = 0;
int testQuick = 0;
int testMerge = 0;
//Check tests
int[] a = new int[1000];
populateArray(a);
int[] select = a;
int[] bubble = a;
int[] quick = a;
int[] merge = a;
testSelection = selectionSort(select);
testBubble = bubbleSort(bubble);
testQuick = quickSort(quick,0,0);
testMerge = mergeSort(merge);
System.out.println("Selection sort number of checks: " + testSelection);
System.out.println("Bubble sort number of checks: " + testBubble);
System.out.println("Quick sort number of checks: " + testQuick);
System.out.println("Merge sort number of checks: " + testMerge);
System.out.println("");
}
public static int[] populateArray(int[] a)
{
Random r = new Random();
a = new int[1000];
for(int i=0; i < a.length; i++)
{
int num = r.nextInt(1000);
a[i] = num;
}
return a;
}
//Sorting methods
public static int selectionSort(int[] a)
{
for (int i = 0; i < a.length; i++)
{
int smallestIndex = i;
for (int j=i; j<a.length; j++)
{
if(a[j]<a[smallestIndex])
{
smallestIndex = j;
}
}
if(smallestIndex != i) //Swap
{
int temp = a[i];
a[i] = a[smallestIndex];
a[smallestIndex] = temp;
selectCount++;
}
}
return selectCount;
}
public static int bubbleSort (int[] a)
{
boolean hasSwapped = true;
while (hasSwapped == true)
{
hasSwapped = true;
for(int i = 0; i<a.length-1; i++)
{
if(a[i] > a[i+1]) //Needs to swap
{
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
hasSwapped = true;
bubbleCount++;
}
}
}
return bubbleCount;
}
public static int mergeSort(int [] a)
{
int size = a.length;
if(size<2)//recursive halting point
{
return 0;
}
int mid = size/2;
int leftSize = mid;
int rightSize = size-mid;
int [] left = new int[leftSize];
int [] right = new int[rightSize];
for(int i = 0; i<mid; i++)
{
mergeCount++;
left[i] = a[i];
}
for(int i = mid; i<size; i++)
{
mergeCount++;
right[i-mid]=a[i];
}
mergeSort(left);
mergeSort(right);
//merge
merge(left,right,a);
return mergeCount;
}
private static void merge(int [] left, int [] right, int [] a)
{
int leftSize = left.length;
int rightSize = right.length;
int i = 0;//index of the left array
int j = 0; //index of right array
int k = 0; //index of the sorted array [a]
while(i<leftSize && j<rightSize)
{
if(left[i]<=right[j])
{
a[k] = left[i];
i++;
k++;
}
else
{
a[k] = right[j];
j++;
k++;
}
}
while(i<leftSize)
{
a[k] =left[i];
i++;
k++;
}
while(j<rightSize)
{
a[k] =right[j];
j++;
k++;
}
}
public static int quickSort(int[] a, int left, int right)
{
//partition, where pivot is picked
int index = partition(a,left,right);
if(left<index-1)//Still elements on left to be sorted
quickSort(a,left,index-1);
if(index<right) //Still elements on right to be sorted
quickSort(a,index+1,right);
quickCount++;
return quickCount;
}
private static int partition(int[] a, int left, int right)
{
int i = left;
int j = right; //Left and right are indexes
int pivot = a[(left+right/2)]; //Midpoint, pivot
while(i<j)
{
while(a[i]<pivot)
{
i++;
}
while(a[j]>pivot)
{
j--;
}
if(i<=j) //Swap
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
return i;
}
}
Your infinite loop is in bubbleSort:
public static int bubbleSort(int[] a)
{
boolean hasSwapped = true;
while (hasSwapped == true)
{
hasSwapped = false; // Need to set this to false
for (int i = 0; i < a.length - 1; i++)
{
if (a[i] > a[i + 1]) // Needs to swap
{
int temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
hasSwapped = true;
bubbleCount++;
}
}
}
return bubbleCount;
}
The problem is in your bubbleSort() method. The hasSwapped boolean is never set to false, so the while loops infinite times.
There is another problem in your code. In the main method, you will have to assign the array that the populateArray() method returns back to a. And the such assignments as int[] select = a; you do in the main method do not do what you want to do. Instead, just send the array a to your sorting methods.
Like this:
int[] a = new int[1000];
a=populateArray(a);
testSelection = selectionSort(a);
testBubble = bubbleSort(a);
testQuick = quickSort(a,0,0);
testMerge = mergeSort(a);

What is wrong the the merge function in my mergesort code?

Sorry, beginner here.This is what I have right now:
public class MergeSort
{
public static void main(String[] args)
{
int[] arr = {3, 5, 2, 4, 1};
sort(arr, 0, arr.length - 1);
for(int i = 0; i < arr.length; i++)
{
System.out.print(arr[i] + " ");
}
}
private static void sort(int[] arr, int lo, int hi)
{
if(lo >= hi)
{
return;
}
int mid = (lo + hi)/2;
sort(arr, lo, mid);
sort(arr, mid + 1, hi);
int size = hi - lo + 1;
int[] temp = new int[size]; //new array to merge into
merge(arr, temp, lo, mid + 1, hi);
for(int i = 0; i < size; i++)
{
arr[i + lo] = temp[i];
}
}
private static void merge(int[] arr, int[] temp, int lower, int mid, int upper)
{
int tempIndex = 0;
int leftLo = lower;
int leftHi = mid - 1;
int rightLo = mid;
int rightHi = upper;
while(leftLo <= leftHi && rightLo <= rightHi)
{
if(arr[leftLo] < arr[rightLo])
{
temp[tempIndex] = arr[leftLo];
tempIndex++;
leftLo++;
}
else
{
temp[tempIndex] = arr[rightLo];
tempIndex++;
rightLo++;
}
}
}
}
I know it's the merge function that is not working, because right now it prints out only the smallest element and the rest as 0's. I think it has something to do with needing another while loop to copy the array, but I don't know how to write that, or even the purpose of it, as right now it seems that the array is being merged into the temp array in a correct order. Why is it only printing the first element correctly? Thanks.
In merge, you copy values as long as leftLo and rightLo both haven't reached their limit yet. Typically one of them reaches early. Then you need to copy the remaining values of the other one. You can copy the remaining elements by adding these two loops:
while (leftLo <= leftHi) {
temp[tempIndex] = arr[leftLo];
tempIndex++;
leftLo++;
}
while (rightLo <= rightHi) {
temp[tempIndex] = arr[rightLo];
tempIndex++;
rightLo++;
}
That is, the complete method becomes:
private static void merge(int[] arr, int[] temp, int lower, int mid, int upper) {
int tempIndex = 0;
int leftLo = lower;
int leftHi = mid - 1;
int rightLo = mid;
int rightHi = upper;
while (leftLo <= leftHi && rightLo <= rightHi) {
if (arr[leftLo] < arr[rightLo]) {
temp[tempIndex] = arr[leftLo];
tempIndex++;
leftLo++;
} else {
temp[tempIndex] = arr[rightLo];
tempIndex++;
rightLo++;
}
}
while (leftLo <= leftHi) {
temp[tempIndex] = arr[leftLo];
tempIndex++;
leftLo++;
}
while (rightLo <= rightHi) {
temp[tempIndex] = arr[rightLo];
tempIndex++;
rightLo++;
}
}

Adding Data Values to a Search Algorithm?

How do I add say 1000, 10000, 1000000, or 10000000 individual data items to a search algorithm?
Code:
public class BinarySearch {
int binarySearch(int[] array, int value, int left, int right) {
if (left > right)
return -1;
int middle = (left + right) / 2;
if (array[middle] == value)
return middle;
else if (array[middle] > value)
return binarySearch(array, value, left, middle - 1);
else
return binarySearch(array, value, middle + 1, right);
}
}
So, if I understand correctly, you want to try your algorithm with different amounts of integers in your array.
public int[] makeArray(int size, int minNum, int maxNum) {
int [] arr = new int[size];
Random r = new Random();
for (int i = 0; i < size; i++) {
arr[i] = minNum + r.nextInt(maxNum);
}
Arrays.sort(arr);
return arr;
}
So if you want to have 10000 numbers ranging from 100 to 500, then you would call:
int[] arr = makeArray(10000, 100, 500);
Actually, I recommend making a helper method to start off your searches like so:
public int binarySearch(int[] array, int value) {
return binarySearch(array, value, 0, array.length - 1);
}
Then you can look in arr for a value (e.g., 5):
int i = binarySearch(arr, 5);
It seems that you are asking how to populate the array. Here is one way to do it:
final Random rnd = new Random();
final int n = 100000;
final int[] array = new int[n];
for (int i = 0; i < n; ++i) {
array[i] = rnd.nextInt();
}
Arrays.sort(array);

finding the start and end index for a max sub array

public static void main(String[] args) {
int arr[]= {0,-1,2,-3,5,9,-5,10};
int max_ending_here=0;
int max_so_far=0;
int start =0;
int end=0;
for(int i=0;i< arr.length;i++)
{
max_ending_here=max_ending_here+arr[i];
if(max_ending_here<0)
{
max_ending_here=0;
}
if(max_so_far<max_ending_here){
max_so_far=max_ending_here;
}
}
System.out.println(max_so_far);
}
}
this program generates the max sum of sub array ..in this case its 19,using {5,9,-5,10}..
now i have to find the start and end index of this sub array ..how do i do that ??
This is a C program to solve this problem. I think logic is same for all languages so I posted this answer.
void findMaxSubArrayIndex(){
int n,*a;
int start=0,end=0,curr_max=0,prev_max=0,start_o=0,i;
scanf("%d",&n);
a = (int*)malloc(sizeof(int)*n);
for(i=0; i<n; i++) scanf("%d",a+i);
prev_max = a[0];
for(i=0; i<n; i++){
curr_max += a[i];
if(curr_max < 0){
start = i+1;
curr_max = 0;
}
else if(curr_max > prev_max){
end = i;
start_o = start;
prev_max = curr_max;
}
}
printf("%d %d \n",start_o,end);
}
Fixing Carl Saldanha solution:
int max_ending_here = 0;
int max_so_far = 0;
int _start = 0;
int start = 0;
int end = -1;
for(int i=0; i<array.length; i++) {
max_ending_here = max_ending_here + array[i];
if (max_ending_here < 0) {
max_ending_here = 0;
_start = i+1;
}
if (max_ending_here > max_so_far) {
max_so_far = max_ending_here;
start = _start;
end = i;
}
}
Here is algorithm for maxsubarray:
public class MaxSubArray {
public static void main(String[] args) {
int[] intArr={3, -1, -1, -1, -1, -1, 2, 0, 0, 0 };
//int[] intArr = {-1, 3, -5, 4, 6, -1, 2, -7, 13, -3};
//int[] intArr={-6,-2,-3,-4,-1,-5,-5};
findMaxSubArray(intArr);
}
public static void findMaxSubArray(int[] inputArray){
int maxStartIndex=0;
int maxEndIndex=0;
int maxSum = Integer.MIN_VALUE;
int cumulativeSum= 0;
int maxStartIndexUntilNow=0;
for (int currentIndex = 0; currentIndex < inputArray.length; currentIndex++) {
int eachArrayItem = inputArray[currentIndex];
cumulativeSum+=eachArrayItem;
if(cumulativeSum>maxSum){
maxSum = cumulativeSum;
maxStartIndex=maxStartIndexUntilNow;
maxEndIndex = currentIndex;
}
if (cumulativeSum<0){
maxStartIndexUntilNow=currentIndex+1;
cumulativeSum=0;
}
}
System.out.println("Max sum : "+maxSum);
System.out.println("Max start index : "+maxStartIndex);
System.out.println("Max end index : "+maxEndIndex);
}
}
Here is a solution in python - Kadane's algorithm extended to print the start/end indexes
def max_subarray(array):
max_so_far = max_ending_here = array[0]
start_index = 0
end_index = 0
for i in range(1, len(array) -1):
temp_start_index = temp_end_index = None
if array[i] > (max_ending_here + array[i]):
temp_start_index = temp_end_index = i
max_ending_here = array[i]
else:
temp_end_index = i
max_ending_here = max_ending_here + array[i]
if max_so_far < max_ending_here:
max_so_far = max_ending_here
if temp_start_index != None:
start_index = temp_start_index
end_index = i
print max_so_far, start_index, end_index
if __name__ == "__main__":
array = [-2, 1, -3, 4, -1, 2, 1, 8, -5, 4]
max_subarray(array)
In python solving 3 problem i.e., sum, array elements and index.
def max_sum_subarray(arr):
current_sum = arr[0]
max_sum = arr[0]
curr_array = [arr[0]]
final_array=[]
s = 0
start = 0
e = 0
end = 0
for i in range(1,len(arr)):
element = arr[i]
if current_sum+element > element:
curr_array.append(element)
current_sum = current_sum+element
e += 1
else:
curr_array = [element]
current_sum = element
s = i
if current_sum > max_sum:
final_array = curr_array[:]
start = s
end = e
max_sum = current_sum
print("Original given array is : ", arr)
print("The array elements that are included in the sum are : ",final_array)
print("The starting and ending index are {} and {} respectively.".format(start, end))
print("The maximum sum is : ", max_sum)
# Driver code
arr = [-12, 15, -13, 14, -1, 2, 1, -5, 4]
max_sum_subarray(arr)
By Om Prasad Nayak
Like This
public static void main(String[] args) {
int arr[]= {0,-1,2,-3,5,9,-5,10};
int max_ending_here=0;
int max_so_far=0;
int start =0;
int end=0;
for(int i=0;i< arr.length;i++){
max_ending_here=max_ending_here+arr[i];
if(max_ending_here<0)
{
start=i+1; //Every time it goes negative start from next index
max_ending_here=0;
}
else
end =i; //As long as its positive keep updating the end
if(max_so_far<max_ending_here){
max_so_far=max_ending_here;
}
}
System.out.println(max_so_far);
}
Okay so there was a problem in the above solution as pointed to Steve P. This is another solution which should work for all
public static int[] compareSub(int arr[]){
int start=-1;
int end=-1;
int max=0;
if(arr.length>0){
//Get that many array elements and compare all of them.
//Then compare their max to the overall max
start=0;end=0;max=arr[0];
for(int arrSize=1;arrSize<arr.length;arrSize++){
for(int i=0;i<arr.length-arrSize+1;i++){
int potentialMax=sumOfSub(arr,i,i+arrSize);
if(potentialMax>max){
max=potentialMax;
start=i;
end=i+arrSize-1;
}
}
}
}
return new int[]{start,end,max};
}
public static int sumOfSub(int arr[],int start,int end){
int sum=0;
for(int i=start;i<end;i++)
sum+=arr[i];
return sum;
}
The question is somewhat unclear but I'm guessing a "sub-array" is half the arr object.
A lame way to do this like this
public int sum(int[] arr){
int total = 0;
for(int index : arr){
total += index;
}
return total;
}
public void foo(){
int arr[] = {0,-1,2,-3,5,9,-5,10};
int subArr1[] = new int[(arr.length/2)];
int subArr2[] = new int[(arr.length/2)];
for(int i = 0; i < arr.length/2; i++){
// Lazy hack, might want to double check this...
subArr1[i] = arr[i];
subArr2[i] = arr[((arr.length -1) -i)];
}
int sumArr1 = sum(subArr1);
int sumArr2 = sum(subArr2);
}
I image this might not work if the arr contains an odd number of elements.
If you want access to a higher level of support convert the primvate arrays to a List object
List<Integer> list = Arrays.asList(arr);
This way you have access to a collection object functionality.
Also if you have the time, take a look at the higher order functional called reduce. You will need a library that supports functional programming. Guava or lambdaJ might have a reduce method. I know that apache-commons lacks one, unless you want to hack to together it.
The only thing I have to add (to several solutions posted here) is to cover the case that all the integers are negative, in which case the max sub array will be just the max element. Pretty easy to do that.. just have to track max element and index of the index of the max element as you iterate through it. If the max element is negative, return it's index instead.
There is also the case of overflow to possibly handle. I've seen algorithm tests that take than into account.. IE, suppose MAXINT was one of the elements and you tried to add to it. I believe some of the Codility (coding interview screeners) tests take that into account.
public static void maxSubArray(int []arr){
int sum=0,j=0;
int temp[] = new int[arr.length];
for(int i=0;i<arr.length;i++,j++){
sum = sum + arr[i];
if(sum <= 0){
sum =0;
temp[j] = -1;
}else{
temp[j] = i;
}
}
rollback(temp,arr);
}
public static void rollback(int [] temp , int[] arr){
int s =0,start=0 ;
int maxTillNow = 0,count =0;
String str1 = "",str2="";
System.out.println("============");
// find the continuos index
for(int i=0;i<temp.length;i++){
if(temp[i] != -1){
s += arr[temp[i]];
if(s > maxTillNow){
if(count == 0){
str1 = "" + start;
}
count++;
maxTillNow = s;
str2 = " " + temp[i];
}
}else{
s=0;
count =0;
if(i != temp.length-1)
start = temp[i+1];
}
}
System.out.println("Max sum will be ==== >> " + maxTillNow);
System.out.print("start from ---> "+str1 + " end to --- >> " +str2);
}
public void MaxSubArray(int[] arr)
{
int MaxSoFar = 0;
int CurrentMax = 0;
int ActualStart=0,TempStart=0,End = 0;
for(int i =0 ; i<arr.Length;i++)
{
CurrentMax += arr[i];
if(CurrentMax<0)
{
CurrentMax = 0;
TempStart = i + 1;
}
if(MaxSoFar<CurrentMax)
{
MaxSoFar = CurrentMax;
ActualStart = TempStart;
End = i;
}
}
Console.WriteLine(ActualStart.ToString()+End.ToString());
}
An O(n) solution in C would be :-
void maxsumindex(int arr[], int len)
{
int maxsum = INT_MIN, cur_sum = 0, start=0, end=0, max = INT_MIN, maxp = -1, flag = 0;
for(int i=0;i<len;i++)
{
if(max < arr[i]){
max = arr[i];
maxp = i;
}
cur_sum += arr[i];
if(cur_sum < 0)
{
cur_sum = 0;
start = i+1;
}
else flag = 1;
if(maxsum < cur_sum)
{
maxsum = cur_sum;
end = i;
}
}
//This is the case when all elements are negative
if(flag == 0)
{
printf("Max sum subarray = {%d}\n",arr[maxp]);
return;
}
printf("Max sum subarray = {");
for(int i=start;i<=end;i++)
printf("%d ",arr[i]);
printf("}\n");
}
Here is a solution in Go using Kadane's Algorithm
func maxSubArr(A []int) (int, int, int) {
start, currStart, end, maxSum := 0, 0, 0, A[0]
maxAtI := A[0]
for i := 1; i < len(A); i++ {
if maxAtI > 0 {
maxAtI += A[i]
} else {
maxAtI = A[i]
currStart = i
}
if maxAtI > maxSum {
maxSum = maxAtI
start = currStart
end = i
}
}
return start, end, maxSum
}
Here is a C++ solution.
void maxSubArraySum(int *a, int size) {
int local_max = a[0];
int global_max = a[0];
int sum_so_far = a[0];
int start = 0, end = 0;
int tmp_start = 0;
for (int i = 1; i < size; i++) {
sum_so_far = a[i] + local_max;
if (sum_so_far > a[i]) {
local_max = sum_so_far;
} else {
tmp_start = i;
local_max = a[i];
}
if (global_max < local_max) {
global_max = local_max;
start = tmp_start;
end = i;
}
}
cout<<"Start Index: "<<start<<endl;
cout<<"End Index: "<<end<<endl;
cout<<"Maximum Sum: "<<global_max<<endl;
}
int main() {
int arr[] = {4, -3, -2, 2, 3, 1, -2, -3, 4,2, -6, -3, -1, 3, 1, 2};
maxSubArraySum(arr, sizeof(arr)/sizeof(arr[0]));
return 0;
}
pair<int,int> maxSumPair(vector<int> arr) {
int n = arr.size();`
int currSum = arr[0], maxSoFar = arr[0];
int start = 0, end ,prev = currSum;
unordered_map<int,pair<int,int>> mp;
for(int i = 1 ; i < n ; i++) {
prev = currSum;
if(currSum == arr[i]) {
end = i-1;
mp.insert({currSum,{start,end}});
start = i;
}
if(maxSoFar < currSum) {
maxSoFar = currSum;
end = i;
mp.insert({currSum,{start,end}});
}
}
int maxSum = INT_MIN;
for(auto it: mp) {
if(it.first > maxSum) {
maxSum = it.first;
}
}
return mp[maxSum];
}
int maxSubarraySum(int arr[], int n){
int max_so_far = -1 * Integer.MAX_VALUE;
int max_curr = 0;
int start = 0;
int end = 0;
for(int i=0; i < arr.length; i++){
max_curr = max_curr + arr[i];
if(max_so_far < max_curr){
max_so_far = max_curr;
}
if( max_curr < 0){
max_curr = 0;
start = i+1;
}
else
end = i;
}
start = end < start ? end : start;
System.out.println( start + "..." + end);
return max_so_far;
}
Maximum sub array in golang implementation
package main
import (
"fmt"
)
func main() {
in := []int{-2, -12, 23, -10, 11, -6, -1}
a, b := max(in)
fmt.Println(a)
fmt.Println(b)
}
func max(in []int) ([]int, int) {
var p, r, sum, sf, psf int
if len(in) == 0 {
return in, 0
}
sum = in[0]
for i, n := range in {
sf += n
if sf > sum {
sum = sf
p = psf
r = i
}
if sf <= 0 {
psf = i + 1
sf = 0
}
}
return in[p : r+1], sum
}
I think this will help to get the start and end index
// Time Complexity = O(N)
// Space Complexity = O(1)
public static int maxSum2(int[] nums){
int globalSum = Integer.MIN_VALUE;
int currentSum = 0;
int start=0;
int end=0;
for(int i=0; i<nums.length;i++){
currentSum += nums[i];
if (currentSum>globalSum){
globalSum = currentSum;
end = i;
}
if (currentSum<0){
currentSum=0;
start = i+1;
}
}
System.out.println(start + " " + end);
return globalSum;
}

Categories