最大子串问题

 

问题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(",", "  ");
	
	}

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值