累加数是一个字符串,组成它的数字可以形成累加序列。
一个有效的累加序列必须至少包含 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
题不难,但是坑很多。
1.怎么处理溢出过大的数
2.遇到0怎么处理
3.如何优化
一
将字符串分成多个数,存在数组中,最后进行判断
class Solution
{
string strllmax;
public:
bool isAdditiveNumber(string num)
{
strllmax = to_string(__LONG_LONG_MAX__);
vector<long long> v;
return DFS(0, num, v);
}
bool DFS(int pos, string num, vector<long long> &nums)
{
if (pos >= num.size())
{
//check
if (nums.size() <= 2)
return false;
for (int i = 2; i < nums.size(); i++)
{
if (nums[i] != nums[i - 1] + nums[i - 2])
return false;
}
return true;
}
long long temp = 0;
for (int i = pos; i < num.size(); i++)
{
//new1
if (num[i] == 0 && i > 1)
break;
string str = num.substr(pos, (i - pos + 1));
if (str.size() > strllmax.size() || str.size() == strllmax.size() && str > strllmax)
break;
temp = temp * 10 + num[i] - '0';
nums.push_back(temp);
if (DFS(i + 1, num, nums))
{
return true;
}
else
{
nums.pop_back();
}
if (temp == 0)
break;
}
return false;
}
};
二
上面版本的优化版
class Solution
{
public:
string long_max;
bool isAdditiveNumber(string num)
{
vector<long long> nums;
long_max = to_string(__LONG_LONG_MAX__);
return DFS(nums, num, 0, num.size());
}
bool isvalid(vector<long long> &nums)
{
if (nums.size() < 3)
return false;
for (int i = 2; i < nums.size(); i++)
{
long long a = nums[i - 2];
long long b = nums[i - 1];
long long c = nums[i];
if (a + b != c)
return false;
}
return true;
}
bool DFS(vector<long long> &nums, string &str, int pos, int N)
{
if (pos == N)
{
return isvalid(nums);
}
for (int i = 1; i <= N - pos; i++)
{
if (str[pos] == '0' && i > 1)
break;
string sub = str.substr(pos, i);
if (sub.size() > long_max.size() || sub.size() == long_max.size() && sub.compare(long_max) > 0)
break;
nums.push_back(stoll(sub));
if ((nums.size() > 2 && !isvalid(nums)) || !DFS(nums, str, pos + i, N))
{
nums.pop_back();
}
else
{
return true;
}
}
return false;
}
};
三
最好的写法:
class Solution
{
public:
bool isAdditiveNumber(string num)
{
for (int i = 1; i <= num.size() / 2; i++)
for (int j = 1; j <= (num.size() - i) / 2; j++)
if (check(num.substr(0, i), num.substr(i, j), num.substr(i + j)))
return true;
return false;
}
private:
bool check(string num1, string num2, string num)
{
if ((num1.size() > 1 && num1[0] == '0') or (num2.size() > 1 && num2[0] == '0'))
return false;
auto sum = add(num1, num2);
if (sum == num)
return true;
if (num.size() <= sum.size() or sum != num.substr(0, sum.size()))
return false;
else
return check(num2, sum, num.substr(sum.size()));
}
string add(string s1, string s2)
{
string res;
int carry(0);
int i(s1.size() - 1), j(s2.size() - 1);
while (i >= 0 || j >= 0)
{
int sum = carry + ((i >= 0) ? (s1[i--] - '0') : 0) + ((j >= 0) ? (s2[j--] - '0') : 0);
res.push_back((sum % 10) + '0');
carry = sum / 10;
}
if (carry)
res.push_back(carry + '0');
reverse(res.begin(), res.end());
return res;
}
};