题目描述
Additive number is a string whose digits can form additive sequence.
A valid additive sequence should contain at least three numbers. Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.
Given a string containing only digits '0'-'9'
, write a function to determine if it's an additive number.
Note: Numbers in the additive sequence cannot have leading zeros, so sequence 1, 2, 03
or 1, 02, 3
is invalid.
题目大意
字符串中包含‘0’-‘9’的数字,要求判断该数字字符串是否是可加序列。
(可加序列:前两个数字相加等于后一个数字,字符串中的所有数字均满足这个规则)
(PS:数字不会包含前缀‘0’,如‘02’或‘03’等,但会包含后缀‘0’,如‘200’等。此外,输入的数字可能会很大,超过long long)
示例
E1
E2
解题思路
外循环取出两个可能的数字,将数字送入内部递归函数,递归函数内将输入的两个数字相加,并判断是否与后续数字相等,若相等则继续递归,否则返回外层循环从新输入两个数字。
复杂度分析
时间复杂度:O(N2)
空间复杂度:O(N)
代码
class Solution { public: bool isAdditiveNumber(string num) { // 遍历数字字符串,将两个数字依次输入递归函数 for(int i = 1; i <= (num.length() / 2); ++i) { for(int j = 1; j <= (num.length() - i) / 2; ++j) { if(solve(num.substr(0, i), num.substr(i, j), num.substr(i + j))) return true; } } return false; } bool solve(string s1, string s2, string num) { // 如果两个数字其中有一个包含前缀0,则返回false if((s1.length() > 1 && s1[0] == '0') || (s2.length() > 1 && s2[0] == '0')) return false; // 计算两个数字之和 string sum = add(s1, s2); // 如果两个数字之和与剩余的字符串数字相等,则返回true if(sum == num) return true; // 否则,如果两个数字之和与后续字符串数字不匹配则返回false if(sum.length() >= num.length() || sum.compare(num.substr(0, sum.length())) != 0) return false; // 除了以上各个情况,进入下一层递归 else return solve(s2, sum, num.substr(sum.size())); } // 计算两个字符串数字的和 string add(string s1, string s2) { string res = ""; int i = s1.length() - 1, j = s2.length() - 1, carry = 0; while(i >= 0 || j >= 0) { int x = carry + (i >= 0 ? s1[i--] - '0' : 0) + (j >= 0 ? s2[j--] - '0' : 0); res.push_back('0' + x % 10); carry = x / 10; } if(carry) res.push_back('0' + 1); reverse(res.begin(), res.end()); return res; } };