题目
题解
class Solution {
public:
bool isAdditiveNumber(string num) {
int n = num.size();
for (int secondStart = 1; secondStart < n - 1; ++secondStart) //第一个结点的循环
{
if (num[0] == '0' && secondStart != 1) {//对第一个数进行判断防止01出现
break;
}//for
for (int secondEnd = secondStart; secondEnd < n - 1; ++secondEnd) {//第二个结点的循环
if (num[secondStart] == '0' && secondStart != secondEnd) {//对第二个数判断防止出现01
break;
}
if (valid(secondStart, secondEnd, num)) {
return true;
}
}
}
return false;
}
//直接把first,second,third当作字符串类型
bool valid(int secondStart, int secondEnd, string num) {//直接判断是否符合函数
int n = num.size();
int firstStart = 0, firstEnd = secondStart - 1;
while (secondEnd <= n - 1) {
string third = stringAdd(num, firstStart, firstEnd, secondStart, secondEnd);//调用字符串相加函数
int thirdStart = secondEnd + 1;
int thirdEnd = secondEnd + third.size();//第3个数的下标结尾是第二个末尾+第三个长度
if (thirdEnd >= n || num.substr(thirdStart, thirdEnd - thirdStart + 1) !=third) {
break;
}
if (thirdEnd == n - 1) {//到达最后一个数嘿嘿
return true;
}
firstStart = secondStart;//这一个数检验完成,往后检验
firstEnd = secondEnd;
secondStart = thirdStart;
secondEnd = thirdEnd;
}
return false;//没有成功一律算错❌
}
string stringAdd(string s, int firstStart, int firstEnd, int secondStart, int secondEnd) {
string third;
int carry = 0, cur = 0;
while (firstEnd >= firstStart || secondEnd >= secondStart || carry != 0) {
cur = carry;
if (firstEnd >= firstStart) {
cur += s[firstEnd] - '0';//把字符类型转化为整型
--firstEnd;//个位-十位这样前缩 第一个数
}
if (secondEnd >= secondStart) {
cur += s[secondEnd] - '0';
--secondEnd;// 第二个数
}
carry = cur / 10;
cur %= 10;
third.push_back(cur + '0');
}
reverse(third.begin(), third.end());//将第三个数位置的字符子串倒序
return third;
}
};
思路:
1)总体上使用二重循环进行划分来判断是否正确
2)要循环内嵌if语句break避免01或者0022这样的数字出现
3)然后这可以看作一个分块问题,把第一个数字解决掉然后看后面的
官方思路
方法一:穷举累加序列第一个数字和第二个数字的所有可能性
思路及解法
一个累加序列,当它的第一个数字和第二个数字以及总长度确定后,这整个累加序列也就确定了。根据这个性质,我们可以穷举累加序列的第一个数字和第二个数字的所有可能性,对每个可能性,进行一次合法性的判断。当出现一次合法的累加序列后,即可返回 true。
当所有可能性都遍历完仍无法找到一个合法的累加序列时,返回 false
记字符串 num 的长度为 n 序列最新确定的两个数中,位于前面的数字为 first first 的最高位在 num 中的下标为 firstStart first 的最低位在 num 中的下标为 firstEnd 记序列最新确定的两个数中,位于后面的数字为 second second 的最高位在 num中的下标为 secondStart second 的最低位在 num中的下标为 secondEnd 在穷举第一个数字和第二个数字的过程中,容易得到以下两个结论: firstStart=0 firstEnd+1=secondStart 因此,我们只需要用两个循环来遍历 secondStart 和 secondEnd 所有可能性的组合即可。
在判断累加序列的合法性时,用字符串的加法来算出 first 与 second之和 third 将 third与 num 接下来紧邻的相同长度的字符串进行比较。
当 third 过长或者与接下来的字符串不相同时,则说明这不是一个合法的累加序列。当相同时,则我们为这个序列新确定了一个数字。
如果 third 刚好抵达 num 的末尾时,则说明这是一个合法的序列。
当 num 还有多余的字符时,则需要更新 firstStart,firstEnd,secondStart,secondEnd 继续进行合法性的判断。
当输入规模较小时,这题可以直接使用整形或者长整型的数字的相加。而我们这里使用了字符串的加法,因此也能处理溢出的过大的整数输入。
仍需要注意的是,当某个数字长度大于等于 22 时,这个数字不能以 0 开头,这部分的判断可以在两层循环体的开头完成。
链接:力扣
来源:力扣(LeetCode) 著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。