【LeetCode306】累加数
题目描述
累加数 是一个字符串,组成它的数字可以形成累加序列。
一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。
给你一个只包含数字 ‘0’-‘9’ 的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回 true ;否则,返回 false 。
说明:累加序列里的数 不会 以 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
提示:
1 <= num.length <= 35
num 仅由数字(0 - 9)组成
解题思路
这道题官方的题解用的是暴力搜索,但显然这样的题用暴力搜索的效率是非常低下的。
仔细观察后这道题其实和用栈对表达式进行求值的思路是一样的,使用一个栈,对字符串在遍历时进行回溯+dfs。
本题的难点在于如何将多位数的字符串转为数值:其实可以使用C++的stod方法,在深度优先遍历时进行子串的截取,再通过判断递归出口条件看是否满足条件。
算法框架如下:
bool dfs(){
cur;//当前位置
if(num(cur-1)+num(cur-2)!=num(cur)) return false;
if(num.size()==0&&cur>=3) return true;
dfs(cur+1);
return false;
}
代码
class Solution {
public:
bool isAdditiveNumber(string num) {
vector<long double> tmp;
return dfs(num,tmp);
}
bool dfs(string num,vector<long double> tmp){
int n=tmp.size();
if(n>=3&&tmp[n-1]!=tmp[n-2]+tmp[n-3]) return false;
//递归的边界
if(!num.size()&&n>=3) return true;
for(int i=0;i<num.size();i++){
//回溯法
string curString=num.substr(0,i+1);
if(curString[0]=='0'&&curString.length()!=1) continue;//处理0
tmp.push_back(stod(curString));//直接将子串转化为数字
if(dfs(num.substr(i+1),tmp)) return true;
tmp.pop_back();//回溯
}
return false;
}
};