问题1:有一组数字串,求出这组数字串中最大的子串的和。
例如:-2,-4,-7,-20,1,1,1,1,-10,1,1,1,-10,10,10,10,-25,10,10,10,10,10,10,-300
首先,看到这个问题我们最先想到的一种方法就是:找到所有的子串,然后通过依次比较,找到最大的。
接下来我们演示一下这种方法的代码。
public int getMaxValue_strings_num(int[] strings ) {
int maxValue = Integer.MIN_VALUE;
int sum = Integer.MIN_VALUE;
for(int i=0 ; i<strings.length ; i++) {
sum = strings[i];
if(sum > maxValue) {
maxValue = sum;
}
for( int k = i+1 ; k < strings.length ; k++ ) {
sum += strings[k];
if(sum > maxValue) {
maxValue = sum;
}
}
}
return maxValue;
}
这种方法的过程就是,长度为n的数字串
第一层找到的子串:strings[0]、strings[0]strings[1]、strings[0]strings[1]strings[2]、strings[0]……strings[n-1]
第二层找到的子串:strings[1]、strings[1]strings[2]、strings[2]strings[3]strings[4]、strings[1]……strings[n-1]
最后一层找到的子串:strings[n-1]。
这样就找到了全部的数字子串。
当然了这种算法并不是我们想要的最理想的算法。我们希望找到一种时间复杂度为o(n)的算法。接下来演示这种算法。
首先我们需要分情况考虑。
第一种情况:这组数字串都是正数,那么很好考虑,最大的子串就是它本身嘛。
第二种情况:这组数字串都是负数,相对也好考虑,因为 负数a+负数b 肯定小于负数a,也小于负数b,最大的数字子串肯 定就是最大的某一个负数。所以遍历一遍就可以了,这里就不演示了。
第三种情况:这组数字串有正有负怎么办,废话不说,直接上算法。
public int getMaxNum_n_1(int[] a) {
int maxNum = 0;
int positiveNum = 0;
for(int i = 0;i < a.length;i++) {
positiveNum += a[i];
if(positiveNum < 0) {
positiveNum = 0;
}
if(positiveNum > maxNum) {
maxNum = positiveNum;
}
}
return maxNum;
}
这个算法的核心思想就是:
有一个maxNum保存最大的子串之和。
有一个positiveNum保存当前为正的子串。
循环一遍,一旦positiveNum < 0,直接舍弃,把它 = 0,因为它一旦 < 0,对于后边的子串来说是没有意义的,
因为负数 + 正数 < 正数。
一旦,positiveNum > maxNum,就让 maxNum = positiveNum 。最终的maxNum 就是我们想要的最大子串的和。
那么问题来了,有没有一种算法可以同时适用于上边三种情况呢,哎,因为俺智力受限,我就不解释这种算法了,直接上算法!
public int getMaxNum_n(int[] a) {
int maxNum = a[0];
int positiveNum = a[0];
if(a[0] <= 0)
positiveNum = 0;
for(int i = 1 ; i < a.length ; i++) {
positiveNum += a[i];
if( positiveNum > maxNum ) {
maxNum = positiveNum;
}
if( positiveNum < 0 ) {
positiveNum = 0;
}
}
return maxNum;
}
问题2:有一组数字串,输出这组数字串中最大的子串。
这个问题就更难了,俺更不解释了。。。。。。哎。。。。。。。直接上算法。。。。。。。。。。。
static String max(int num[]) {
int maxNum = num[0];
int positiveNum = num[0];
if( num[0] <= 0 ) positiveNum = 0;
String maxString = "-2";
String positiveStr = "";
for(int i = 1 ;i < num.length ; i++) {
positiveNum += num[i];
positiveStr += "," + num[i];
if( positiveNum > maxNum ) {
maxNum = positiveNum;
maxString = positiveStr;
}
if( positiveNum < 0 ) {
positiveNum = 0;
positiveStr = "";
}
}
return maxString.replace(",", " ");
}