leetcode-累加数(C++)
累加数是一个字符串,组成它的数字可以形成累加序列。
一个有效的累加序列必须至少包含 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
进阶:
你如何处理一个溢出的过大的整数输入?
思路:两个for循环获得初始的3个数,当我们探索下去这三个数不成立的话,可以通过For循环增大位数,继续比较下去,如果出现了比较成立,直接返回True。
在比较这三个数,探索的情况下,我们用DFS来处理。获得的三个数,num1+num2==num3.substr,因此DFS也要不断更新num1,num2,num.substr。
注意到如果首位为“0” 那么要跳过。
我们是通过字符串来比较三个数的,因此再写一个字符串整数相加的算法。(字符串相加为大整数运算,同时解决了溢出问题)
class Solution { public: string getSum(string& num1,string& num2){ //两个字符串表示的数字相加的算法,最后返回一个字符串sum int val,flag=0,len1=num1.size(),len2=num2.size(); string sum; while(len1||len2){ //字符串相加,从个位数到百位,千位,万位 int val=0; //每一位数的和 if(len1>0) {val+=num1[len1-1]-'0'; len1--;} if(len2>0){val+=num2[len2-1]-'0'; len2--;} sum+=to_string((val+flag)%10); flag=(val+flag)/10; } if(flag)sum+="1"; //最后的进位要加上去 reverse(sum.begin(),sum.end()); return sum; } bool dfs(string& num1,string& num2,string& num3){ //num1,num2相加是否等于后面的数字,同时探索到最后一个数字 if(num3.size()==0)return true; string sum=getSum(num1,num2); for(int i=1;i<=num3.size();i++){ string str=num3.substr(0,i), tem=num3.substr(i); if(str==sum&&dfs(num2,sum,tem))return true; //三个数字分别为num2,sum,tem if(num3[0]=='0')break; //"0"在首位那么跳过 } return false; } bool isAdditiveNumber(string num) { if(num.size()<3)return false; int size=num.size(); for(int i=1;i<size-1;i++){ string num1=num.substr(0,i); //先获得三个数字,i从1开始,就是获得三个个位数 for(int j=i+1;j<size;j++){ //c++的substr函数是string.substr(index,len) len表示切割的长度。 如s=“0123456" s.substr(4)="456" string num2=num.substr(i,j-i); string num3=num.substr(j); if(dfs(num1,num2,num3))return true; if(num[i]=='0')break; } if(num[0]=='0')break; } return false; } };