累加数是一个字符串,组成它的数字可以形成累加序列。

一个有效的累加序列必须至少包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。

给定一个只包含数字 '0'-'9' 的字符串,编写一个算法来判断给定输入是否是累加数。

说明: 累加序列里的数不会以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。

示例 1:

输入: "112358"
输出: true 
解释: 累加序列为: 1, 1, 2, 3, 5, 8 。1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
示例 2:

输入: "199100199"
输出: true 
解释: 累加序列为: 1, 99, 100, 199。1 + 99 = 100, 99 + 100 = 199
进阶:
你如何处理一个溢出的过大的整数输入?

 

思路:

本题的难点就是确定前两个数  由于至少有三个数  所以第一个数的长度最大只能为length/2 

第二个数从第一个数后面开始,第三个数从第二个数后面开始,我们首先知道,第三个数肯定至少和第一个数与第二个数
一样大,因为是和嘛,若第二个数从i开始到j-1结束,那么第三个数长度最大为L-j,这个长度一定大于等于第一个数和第二个数长度的较大者,即:L-j>=i && L-j>=j-i。 
确定了第二个数的范围之后问题就简单了,看看能不能构成加法序列,只要判断剩下的字串是不是以sum开头即可,然后递归判定

 public boolean isAdditiveNumber(String num) {
		     int len = num.length();
	        //确定第一个数,最终用num.subStr(0,i)来确定第一个数,所以i可以用来标示第一个数的长度,
	        //但是下标i不包含在第一个数中
	        for(int i=1;i<=len/2;i++){
	            //如果长度大于等于2,则不能以0开头
	            if(num.startsWith("0") && i>=2) break;

	            //确定第二个数,第一个数用num.subStr(i,j),包括i,不包括j,所以长度为j-i,
	            //第三个数从下标j开始,长度最长为L-1-j+1,即L-j
	            for(int j=i+1;(len-j)>=i && (len-j)>=j-i;j++){
	                if(num.charAt(i)=='0' && j-i>=2) break;

	                long num1 = Long.parseLong(num.substring(0,i));
	                long num2 = Long.parseLong(num.substring(i,j));

	                if(isValid(num.substring(j), num1, num2)){
	                    return true;
	                }
	            }
	        }
	        return false;
	    }

	    //判断由num1,num2和后续的字串能否构成加法序列
	    public boolean isValid(String remain,long num1,long num2){

	        if(remain.equals("")) return true; //没有剩下的了
	        long sum = num1+num2;

	        String sumStr = ""+sum;
	        if(!remain.startsWith(sumStr)) return false;
	        return isValid(remain.substring(sumStr.length()), num2, sum);
	    }