您的位置:首页 > 职场人生

面试题五:求子数组的最大和

2014-04-17 13:49 218 查看
5.求子数组的最大和

题目:

输入一个整形数组,数组里有正数也有负数。

数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。

求所有子数组的和的最大值。要求时间复杂度为 O(n)。

a[] = {-2,3,-1,4,-7,-3,4,5,-2}

像这个数组的最大子数组是{4,5}

思路一:这种情况时间复杂度大于0(n);

 -2,3,-1,4,-7,-3,4,5,-2

a.开辟两个下标值,一个start,一个end,start指向最大子数组的头部,end指向最大子数组的尾部。初始化让start=0,end=0,都指向a[0].

b.首先找到end的位置,当end指向的是一个正数,直接end++;如果end指向的负数,判断负数右边有没有和比这个负数的绝对值大的数,如果有则让end=i;

c.找到end的位置后,下面去确定start的位置就好确定,只要找出从下标0到end处的所有子数组,中哪个是最大的。

package com.wukung.blog;

/**
* @author WuKung
* @csdnURL http://blog.csdn.net/wu_kung/ * @createdDate 2014-4-10 下午9:34:27
*/
public class MaxSubSequence {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

int a[] = { -3, 1, 3, -1, -4, 0, -10, 11, 7, -5 };
int max = 0;
int b = 0, s = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] >= 0) {
b = i;
} else {
int temp;
int sum=0;
for (temp = i; temp < a.length; temp++) {
sum += a[temp];
if (sum >= 0) {
b = i;
break;
}
}
}
}

int t = a[b];
max = a[b];
s=b;
for (int i = b - 1; i >= 0; i--) {
t += a[i];
if (max <= t) {
s = i;
max = t;
}

}

for (int j = s; j <= b; j++) {
System.out.print(a[j] + " ");
}

}
}

思路二:时间复杂度O(n)的算法

其实算法很简单,当前面的几个数,加起来后,b<0后,

把 b 重新赋值,置为下一个元素,b=a[i]。

当 b>sum,则更新 sum=b;

若 b<sum,则 sum 保持原值

package com.wukung.blog;

/**
* @author WuKung
* @csdnURL http://blog.csdn.net/wu_kung/ * @createdDate 2014-4-10 下午11:28:26
*/
public class MaxTest {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

int[] a = {-2,3,-1,4,-7,-3,4,5,-2};
System.out.println("输出最大子数组序列");
System.out.println(maxSum(a, a.length));

}

public static int maxSum(int[] a, int n)
{
int sum=0;
int b=0;

int start=0,end=0;
//针对数组全部为负数的判断。
int nTemp=a[0];
for(int j=1; j<n; j++)
{
if (nTemp<a[j])
nTemp=a[j];
}
if (nTemp<0)
return nTemp;
for(int i=0; i<n; i++)
{
if(b<0){
start=i;
b=a[i];
}
else
b+=a[i];
if(sum<b){
end=i;
sum=b;
}
}

for(int k=start;k<=end;k++){
System.out.print(a[k]+" ");
}
System.out.println();
System.out.println("输出最大子数组的和:");
return sum;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试题