LeetCode/solutions/306. Additive Number.md
2019-11-11 13:10:11 +08:00

2.4 KiB
Raw Blame History

306. Additive Number

思路

定义一种加法序列:除前两个数外,每个数字都是其前面两个数字的和。题目要求一个字符串序列是否可以分割成一个加法序列。

这题其实没有很好的方法就是brute force。因为加法序列有一个特点一旦前两个数确定了那么后面每个数就确定了。所以我们暴力枚举前两个数的所有情况然后再 不断得到下一个数的值并判断得到的字符串是否和目标串相同若是则返回True。由于follow up说了要处理int整数溢出的情况所以我们可以使用long long型或者自己写一个大数相加的函数就是题415. Add Strings)。

C++

class Solution {
private:
    string big_add(string n, string m){ // 大数相加
        string res;
        int i=n.size() - 1, j= m.size() - 1, carry = 0;
        while(i>=0 || j>=0){
            int sum=carry+(i>=0 ? (n[i--]-'0') : 0) + (j>=0?  (m[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;
    }
public:
    bool isAdditiveNumber(string num) {
        int len = num.size();
        for(int i = 1; i <= len / 2; i++){
            if(num[0] == '0' && i > 1) continue; // 前导0
            for(int j = 1;j <= len / 2; j++){
                if(num[i] == '0' && j > 1) continue; // 前导0
                string num1_str = num.substr(0, i);
                string num2_str = num.substr(i, j);
                string accum_str = num1_str + num2_str;
                
                if(accum_str != num.substr(0, accum_str.size())) continue;
                while(accum_str.size() < len){
                    // string num3_str = to_string(stol(num1_str) + stol(num2_str));
                    string num3_str = big_add(num1_str, num2_str);
                    
                    if(num3_str != num.substr(accum_str.size(), num3_str.size())) break;           
                    accum_str += num3_str;
                    if(accum_str.size() == len) return true;
        
                    num1_str = num2_str;
                    num2_str = num3_str;
                }
            }
        }
        return false;
    }
};