-
累加数 是一个字符串,组成它的数字可以形成累加序列。
-
一个有效的 累加序列 必须 至少 包含 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
1 <= num.length <= 35
num 仅由数字(0 - 9)组成
题解
- 使用两个分割的指针分割,然后使用函数判断分割后的字符串能否满足要求。
- 还需注意字符串的操作超过int(4byte = 4*8 =32二进制)的范围。
暴力循环:add string处理数值操作
class Solution {
public:
// 大数加法模板
string add(string& a,string& b){
int n1 = a.size()-1;
int n2 = b.size()-1;
int carry = 0; //进位符号
string ans;
while(n1>=0||n2>=0||carry>0){
int t1=n1>=0?a[n1--]-'0':0;
int t2=n2>=0?b[n2--]-'0':0;
ans+=(t1+t2+carry)%10+'0';
carry=(t1+t2+carry)/10;
}
reverse(ans.begin(),ans.end());
return ans;
}
//判断分割后的字符串是否满足题意
// num1: [i, j) + num2: [j, k) = sum: [k, ..)
bool valid(string& num, int i, int j, int k) {
if (num[i] == '0' && j != i+1) return false;
if (num[j] == '0' && k != j+1) return false;
string a = num.substr(i, j-i);
string b = num.substr(j, k-j);
string sum = add(a, b);
if (sum.size() + k > num.size()) return false;
for (int s = 0; s <= sum.size() - 1; s++) {
if (sum[s] != num[s+k]) return false;
}
if (sum.size() + k == num.size()) return true;
return valid(num, j, k, sum.size()+k);
}
bool isAdditiveNumber(string num) {
for (int i = 1; i < num.size(); i++) {
for (int j = i+1; j < num.size(); j++) {
if (valid(num, 0, i, j)) return true;
}
}
return false;
}
};
// 链接:https://leetcode.cn/problems/additive-number/solution/wei-rao-li-lun-da-shu-jia-fa-hui-su-yan-9q0d5/
暴力循环: long long int处理数值操作
class Solution {
private:
long long int getNum(const string num, int pos, int len) { //字符串转ll数字,如果非法返回-1;
if (pos != 0 and len != 1 and num[pos] == '0')
return -1;
return stoll(num.substr(pos, len), NULL, 10);
}
public:
bool isAdditiveNumber(string num) {
if (num.size() < 3) return 0;
int a_len = 1;
bool a_f = true;
while (a_len <= floor(num.size() / 2) and a_f) {
int a_pos = 0; //第一个数a总是从0位置开始的
int b_pos = a_pos + a_len; //第二个数的开始位置
int b_len = 1;
bool b_f = true;
while (b_len <= floor((num.size() - a_len) / 2) and a_f and b_f) {
int c_pos = b_pos + b_len; //第三个数的开始位置
int c_len = max(a_len, b_len);//第三个数的起始长度
bool c_f = true;
long long int a = getNum(num, a_pos, a_len);
if (a == -1) {
a_f = false;
break;
}
long long int b = getNum(num, b_pos, b_len);
if (b == -1) {
b_f = false;
break;
}
int a_len_temp = a_len;
int b_len_temp = b_len;
while (c_pos + c_len <= num.size()) {
if (c_len > (max(a_len_temp, b_len_temp) + 1) and c_f)
break;
long long int c = getNum(num, c_pos, c_len);
if (c == -1) {
c_f = false;
break;
}
if (a + b == c) {
//判断后续的数值
a = b;
b = c;
a_len_temp = b_len_temp;
b_len_temp = c_len;
c_pos = c_pos + c_len;
}
else if (a + b > c)
++c_len;//增长c的长度
else if (a + b < c)
break;
if (c_pos == num.size())
return 1; //判断到结尾
}
++b_len;
}
++a_len;
}
return 0;
}
};