I modified the Kadane's algorithm to the following so that it works even in the case wherein I have all negative numbers in the array.
//Largest Sum Contiguous Subarray
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define F(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define RF(i,a,b) for(int i = (int)(a); i >= (int)(b); i--)
#define SIZE 100000
int main (void)
{
vector<int> myvec;
int arr[SIZE];
int index[SIZE] = {0};
int n;
cin>>n;
F(i,0,n)
{
cin>>arr[i];
}
int maxendinghere = arr[0];
int maxsofar = arr[0];
F(i,1,n)
{
if (arr[i] > (arr[i]+maxendinghere))
myvec.pb(i); // used for finding the elements of the subarray
maxendinghere = max(arr[i],arr[i]+maxendinghere);
maxsofar = max(maxendinghere,maxsofar);
}
cout<<maxsofar<<"\n";
auto it = myvec.begin(); // printing the subarray
while (it != myvec.end())
{
cout<<*it<<"\t";
it++;
}
cout<<"\n";
return 0;
}
Now, I am trying to print the actual elements that form the subarray. One thing that I was able to think of was that the everytime (arr[i]+maxendinghere)
will be greater than arr[i]
, a new element will be a part of the subarray and I push that in a vector and print the elements. But this doesn't give out the actual subarray correctly. What am I missing in this thought process? Thanks!
PS: I understand this is not the best coding style, but this was asked in an interview and I was trying to code it. I couldn't back then and hence this is what I was able to come up with.
Edit: Answer) I was able to code it up after the answer given by templatetypedef. The folllowing is the implementation.
//Largest Sum Contiguous Subarray
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define F(i,a,b) for(int i = (int)(a); i < (int)(b); i++)
#define RF(i,a,b) for(int i = (int)(a); i >= (int)(b); i--)
#define SIZE 100000
int main (void)
{
int currsum[SIZE],maxsumsofar[SIZE],sindex[SIZE],eindex[SIZE];
int arr[SIZE];
int start,end,n;
cin>>n;
F(i,0,n)
{
cin>>arr[i];
}
currsum[0] = arr[0];
maxsumsofar[0] = arr[0];
sindex[0] = 0;
eindex[0] = 0;
F(i,1,n)
{
if (arr[i] > (arr[i]+currsum[i-1])) // for starting index
sindex[i] = i;
else
sindex[i] = sindex[i-1];
currsum[i] = max(arr[i],arr[i]+currsum[i-1]);
maxsumsofar[i] = max(currsum[i],maxsumsofar[i-1]);
if (arr[i] > (arr[i]+currsum[i-1]))
eindex[i] = i;
else
{
if (maxsumsofar[i] == maxsumsofar[i-1])
eindex[i] = eindex[i-1];
else
eindex[i] = i;
}
}
cout<<maxsumsofar[n-1]<<"\n";
F(i,0,n)
{
if (maxsumsofar[i] == maxsumsofar[n-1])
{
start = sindex[i];
end = eindex[i];
break;
}
}
cout<<"The array lies between indices "<<start<<" to "<<end<<"\n";
return 0;
}
答案 0 :(得分:1)
Kadane的算法通过维持子阵列的起始位置并反复查看数组中的下一个元素并决定
来工作。如果你明确地跟踪当前子阵列的起始点(最初它在数组的第一个元素之前,并且每当总数下降到零以下时重置),那么找到它不应该太难最佳子阵列。每次更新找到的最大子阵列时,您都可以
您可以通过跟踪目前为止的最大子阵列以及其起始位置来实现此目的。如果max子阵列与当前数组的位置相同,则为(1),否则为case(2)。