累加数 是一个字符串,组成它的数字可以形成累加序列。一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,序列中的每个后续数字必须是它之前两个数字之和。给你一个只包含数字 ‘0’-‘9’ 的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回 true ;否则,返回 false 。说明:累加序列里的数,除数字 0 之外,不会 以 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
思路:给定的 nums 的长度只有 35,而且要求序列的第三个数开始由前两个数相加而来。因此使用 DFS 搜索每个数的分割点,同时利用累加数的特性(第三个数起,每个数均由为前两数之和)进行剪枝。具体的。因为数字不包含前导0,所以当前数字为0时,需要把它单独作为一个数字。如果结果的result集合长度小于2,则可以直接添加current集合,如果大于2则需要进行判断当前集合和前两个集合是否满足题意要求,即a+b是否等于c。
class Solution {
List<List<Integer>> result = new ArrayList<>();
int len;
String num;
public boolean isAdditiveNumber(String num) {
this.num = num;
len = num.length();
return dfs(0);
}
public boolean dfs(int start){
int m = result.size();
if(start == len)
return m >= 3;
List<Integer> current= new ArrayList<>();
int max = num.charAt(start)=='0'?start+1:len;
for(int i = start; i < max; i++){
current.add(0,num.charAt(i)-'0');
if(m < 2 || isTrue(result.get(m-2),result.get(m-1),current)){
result.add(current);
if(dfs(i+1))
return true;
result.remove(result.size()-1);
}
}
return false;
}
public boolean isTrue(List<Integer> a,List<Integer> b,List<Integer> c){
List<Integer> ans = new ArrayList<>();
int temp = 0;
for(int i = 0; i < a.size() || i < b.size(); i++){
if(i < a.size())
temp += a.get(i);
if(i < b.size())
temp += b.get(i);
ans.add(temp%10);
temp /= 10;
}
if(temp > 0){
ans.add(temp);
}
boolean flag = ans.size() == c.size();
for(int i = 0; i < ans.size()&&flag; i++){
if(ans.get(i) != c.get(i)){
flag = false;
}
}
return flag;
}
}