int array[] = {-1, 4, -2, 5, -5, 2, -20, 6};
如果我有那个数组,我的Kadane算法实现找到最大的子数组:
int max_so_far = INT_MIN;
int max_ending_here = 0;
for (int i = 0; i < size; i++) {
max_ending_here = max(max_ending_here + array[i], 0);
max_so_far = max(max_ending_here, max_so_far);
}
printf("%d\n", max_so_far);
但是,如果我有一系列所有底片:
int array[]= {-10, -10, -10};
它不起作用,它应该返回-10,但我得到0。
我怎样才能让它对负数起作用?
谢谢!
答案 0 :(得分:36)
当所有元素都为负数时,最大子数组为空子数组,其总和为0.
但是如果你想在这种情况下改变算法以存储最大的元素,你可以执行以下操作:
int max_so_far = INT_MIN;
int max_ending_here = 0;
int max_element = INT_MIN;
for (int i = 0; i < size; i++)
{
max_ending_here = max(max_ending_here + array[i], 0);
max_so_far = max(max_ending_here, max_so_far);
max_element = max(max_element, array[i]);
}
if (max_so_far == 0)
max_so_far = max_element;
printf("%d\n", max_so_far);
答案 1 :(得分:17)
根据Wikipedia,Kadane的算法需要至少一个正数,因此您的所有负数组都是无效输入。
答案 2 :(得分:3)
对Kadane的算法略作补充。 取一个标志,are_all_elements_negative(设置为true)和一个int(存储最高的-ve整数) 迭代数组时,如果找到正数,则将标志设置为false。 当标志为true时,存储最高的-ve num。最后,检查标志,如果标志为真,则输出-ve整数,否则输出常规的Kadane算法输出。
答案 3 :(得分:1)
int max_so_far = INT_MIN;
int max_ending_here = array[0];
for (int i = 1; i < size; i++) {
max_ending_here = max(max_ending_here + array[i], array[i]);
max_so_far = max(max_ending_here, max_so_far);
}
printf("%d\n", max_so_far);
可能有效
答案 4 :(得分:1)
这是实现目标的另一种选择
int Solution::maxSubArray(const vector<int> &A){
int cs=0,ms=0,l=A.size(),x=0,min;
if(A[0]<0)
min=A[0];
x++;
if(l==1)
return A[0];
for(int i=1;i<A.size();i++){
if(A[i]<0)
x++;
if(A[i]>min)
min=A[i];
else
break;
}
if(x==l)
return min;
for(int i=0;i<A.size();i++){
cs=cs+A[i];
if(cs<0)
cs=0;
ms=max(cs,ms);
}
return ms;
}
答案 5 :(得分:0)
如果所有元素都是负数,则返回最小负数。 在所有其他情况下,您的解决方案都可以正常工作。
printf("%d\n",max(max_so_far, *max_element(array,array+size)) );
答案 6 :(得分:0)
当阵列的所有元素都是负数时,Kadane的算法不起作用。在这种情况下它只返回0。如果你想要处理这个,我们需要在实际实现之前添加额外的阶段。该阶段将查看所有数字是否为负数,如果它们将返回它们的最大值(或绝对值最小)。
我可以建议一个实现
#define find_max_val(x,y) x >= y ?x :y;
int min_sum(int a[],int n){
int min_so_far = a[0],min_end_here = a[0];
for(int i = 1;i < n; i++){
min_end_here = find_max_val(a[i],min_end_here + a[i]);
min_so_far = find_max_val(min_so_far,min_end_here);
}
return min_so_far;
}
还有其他实现取决于需要。
答案 7 :(得分:0)
我参加这个派对的时间已经很晚了,但是这样会有什么作用吗?:
cur_sum = max_sum = sequence[0];
sum_to_j = 0;
for j in range(0, len(sequence)):
sum_to_j += sequence[j];
if sum_to_j > cur_sum:
cur_sum = sum_to_j;
if cur_sum > max_sum:
max_sum = cur_sum
if sum_to_j < 0:
sum_to_j = 0;
cur_sum = sequence[j];
print max_sum;
答案 8 :(得分:0)
如果所有元素都是负数,则按值返回最大元素
boolean allNegative = true;
int bigNegative = Integer.MIN_VALUE;
int maxSum = 0;
int sum = 0;
for(int i=0;i<a.size();i++){
// if all numbers are negative
if(a.get(i)>=0){
allNegative = false;
}else{
if(a.get(i)>bigNegative){
bigNegative = a.get(i);
}
}
sum += a.get(i);
if(sum<0){
sum=0;
}
if(sum>maxSum){
maxSum = sum;
}
}
if(allNegative){
return bigNegative;
}
return maxSum;
答案 9 :(得分:0)
它适用于以下代码。
public int algorithmKadane(int[] input_array){
int sum = input_array[0];
int rotate_sum = input_array[0];
for(int i=1; i< input_array.length ; i++){
rotate_sum = Math.max(input_array[i], rotate_sum+input_array[i]);
sum = Math.max(rotate_sum,sum);
}
return sum;
}
答案 10 :(得分:0)
请参阅wikiped kadane的算法max subarray
int max_subArray(Integer[] input){
int max_so_far,max_ending_here;
max_so_far = max_ending_here =input[0];
for(int i =1; i<input.length;i++){
max_ending_here = Math.max(input[i], input[i]+max_ending_here);
max_so_far = Math.max(max_so_far, max_ending_here);
}
return max_so_far;
}
在你的情况下它将返回-10
答案 11 :(得分:0)
希望该解决方案对于Kadane的算法也能处理所有负数的情况
long long int n,max_f=0,i,max_end=0,s;
cin>>n;
long long int a[n];
for(i=0;i<n;i++)
{
cin>>a[i];
}
long long int *m;
m=max_element(a,a+n);
if(*m<0)
{
s=*m;
}
else {
for(i=0;i<n;i++)
{
max_end= max_end +a[i];
if(max_end<0)
{
max_end=0;
}
if(max_f < max_end)
{
max_f=max_end;
}
s=max_f;
}
}
cout<<s<<endl;
}
答案 12 :(得分:0)
如果我们有一个所有负数的数组,那么数组中的max元素将是结果。
例如:如果数组元素是
-3 -2 -5 -4 -1
最大和子数组为-1。
我们可以添加此检查,看看函数Kadane的返回值是否为0。
(只是O(n)搜索。不会更改时间复杂度:))
代码:
int maxSubArraySum(int a[], int size) {
int max_so_far = INT_MIN, max_ending_here = 0, max_negative_scenario = INT_MIN;
for (int i = 0; i < size; i++) {
max_ending_here = max_ending_here + a[i];
if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
if (max_ending_here < 0){
max_ending_here = 0;
if(a[i] > max_negative_scenario) // additional check
max_negative_scenario = a[i];
}
if(max_so_far == 0) // additional check
max_so_far = max_negative_scenario;
return max_so_far;
}
答案 13 :(得分:0)
根据WIKI
public int maxSubArray(int[] nums) {
int currentSum = 0;
int bestSum = 0;
for (int element : nums) {
currentSum = Math.max(0, currentSum + element);
bestSum = Math.max(bestSum, currentSum);
}
return bestSum;
}
上面的代码对于输入将失败
nums = [-1]
如果输入不包含任何正数元素(包括当输入为空时),此版本的算法将返回0。对于不允许空子数组的问题变体,应将best_sum初始化为负无穷大,并且在for循环中,current_sum也应更新为max(x,current_sum + x)。在那种情况下,如果输入不包含正元素,则返回的值是最大元素的值(即最小负值),如果输入为空,则返回负无穷大。
修改后的否定输入代码:
public int maxSubArray(int[] nums) {
int currentSum = 0;
int bestSum = Integer.MIN_VALUE;
for (int element : nums) {
currentSum = Math.max(element, currentSum + element);
bestSum = Math.max(bestSum, currentSum);
}
return bestSum;
}
答案 14 :(得分:-1)
public static int max_sum(int[] in){
int maxsum=0;
int cursum=0;
for (int i=0;i<in.length;i++){
cursum = in[i]+cursum;
if (cursum>maxsum) {
maxsum = cursum;
}
// for negative value
if (cursum < 0) {
for (int n=0;n<in.length;n++){
maxsum = in[n];
if (cursum>maxsum){
maxsum=cursum;
}
}
}
}
return maxsum;
}
答案 15 :(得分:-2)
我认为以下方法可行: -
int maxSub(vector<int> x){
int sum=x[0],local_max=0;
for(int i=0;i<x.size();i++){
local_max+=x[i];
if(sum < local_max)
sum=local_max;
if(local_max <0)
local_max=0;
}
return sum;
}