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);
}
}
这个程序生成子数组的最大总和..在这种情况下它是19,使用{5,9,-5,10} .. 现在我必须找到这个子数组的开始和结束索引。我这样做吗??
答案 0 :(得分:5)
这是一个解决这个问题的C程序。我认为所有语言的逻辑都是一样的,所以我发布了这个答案。
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);
}
答案 1 :(得分:2)
这是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);
}
}
答案 2 :(得分:2)
修复Carl Saldanha解决方案:
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;
}
}
答案 3 :(得分:1)
这个问题有点不清楚,但我猜测的是一个&#34;子阵列&#34;是一半的对象。
像这样执行此操作的蹩脚方式
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);
}
如果arr包含奇数个元素,我可能无法正常工作。
如果要访问更高级别的支持,请将primvate数组转换为List对象
List<Integer> list = Arrays.asList(arr);
这样您就可以访问集合对象功能。
此外,如果您有时间,请查看名为reduce的更高阶函数。您将需要一个支持函数式编程的库。番石榴或lambdaJ可能有一种减少方法。我知道apache-commons缺少一个,除非你想要共同攻击它。
答案 4 :(得分:1)
这是python中的一个解决方案 - Kadane's algorithm扩展来打印开始/结束索引
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)
答案 5 :(得分:1)
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)
答案 6 :(得分:0)
喜欢这个
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);
}
好的,所以上述解决方案存在问题,如史蒂夫P.所指出的。这是另一个应该适用于所有人的解决方案
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;
}
答案 7 :(得分:0)
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);
}
答案 8 :(得分:0)
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());
}
答案 9 :(得分:0)
我要添加的唯一内容(这里发布的几个解决方案)是覆盖所有整数都是负数的情况,在这种情况下,max子数组将只是max元素。很容易做到这一点..只需要在迭代它时跟踪max元素索引的最大元素和索引。如果max元素为负数,则返回它的索引。
还有可能出现溢出的情况。我已经看过算法测试,而不是考虑到.. IE,假设MAXINT是其中一个元素,你试图添加它。我相信一些Codility(编码面试筛选器)测试考虑到了这一点。
答案 10 :(得分:0)
C中的O(n)解决方案是: -
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");
}
答案 11 :(得分:0)
这是使用Kadane算法的Go解决方案
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
}
答案 12 :(得分:0)
这是C ++解决方案。
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;
}
答案 13 :(得分: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];
}