• 【刷题-LeetCode】306. Additive Number


    1. Additive Number

    Additive number is a string whose digits can form additive sequence.

    A valid additive sequence should contain at least three numbers. Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.

    Given a string containing only digits '0'-'9', write a function to determine if it's an additive number.

    Note: Numbers in the additive sequence cannot have leading zeros, so sequence 1, 2, 03 or 1, 02, 3 is invalid.

    Example 1:

    Input: "112358"
    Output: true
    Explanation: The digits can form an additive sequence: 1, 1, 2, 3, 5, 8. 
                 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
    

    Example 2:

    Input: "199100199"
    Output: true
    Explanation: The additive sequence is: 1, 99, 100, 199. 
                 1 + 99 = 100, 99 + 100 = 199
    

    Constraints:

    • num consists only of digits '0'-'9'.
    • 1 <= num.length <= 35

    Follow up:
    How would you handle overflow for very large input integers?

    • 回溯法。注意回溯中,在进入分支之后,还要退出分支
    • 大数运算。用字符串实现大数的加减乘除
    // 大数,只需要重载加法
    class BigNum{
    public:
        string val;
        BigNum(string s, bool hasreversed = false){
            if(!hasreversed){
                reverse(s.begin(), s.end());
            }
            val = s;
        }
        void Print(){
            for(int i = val.size()-1; i>=0; --i)cout << val[i];
            cout << endl;
        }
        //先加两个字符串公有的部分,再加上剩下的部分
        //如果进位不为0,还要加上进位
        BigNum operator + (BigNum &b){
            string s1 = b.val, res;
            int carry = 0, i = 0;
            while(i < s1.size() && i < val.size()){
                int tmp = carry + (s1[i]-'0') + (val[i]-'0');
                carry = tmp / 10;
                res += tmp % 10 + '0';
                i++;
            }
            while(i < s1.size()){
                int tmp = carry + (s1[i]-'0');
                carry = tmp / 10;
                res += tmp % 10 + '0';
                i++;
            }
            while(i < val.size()){
                int tmp = carry + (val[i]-'0');
                carry = tmp / 10;
                res += tmp % 10 + '0';
                i++;
            }
            if(carry)res += carry + '0';
            return BigNum(res, true);
        }
    };
    
    class Solution {
    public:
        bool isAdditiveNumber(string num) {
            vector<BigNum>path;
            return dfs(num, 0, path);
        }
        bool dfs(string &num, int pos, vector<BigNum>&path){
            //结束条件,当pos到达了字符串末尾,则枚举完毕,看path的长度,如果大于2,说明前面的枚举是成功的
            if(pos >= num.size())return path.size() >= 3;
            int len = path.size();
            // 如果len<2,说明最前面的两个数字还没有选出来,枚举选择即可
            // 不能出现前缀0,即02 00这些是不合法的,只能选成0
            if(len < 2){
                for(int i = 1; i <= num.size(); ++i){
                    if(num[0] == '0' && i > 1)break;
                    path.push_back(BigNum(num.substr(0, i)));
                    for(int j = i+1; j <= num.size(); ++j){
                        if(num[i] == '0' && j > i + 1)break;
                        path.push_back(BigNum(num.substr(i, j-i)));
                        if(dfs(num, j, path)){
                            return true;
                        }else{
                            path.pop_back();
                        }
                    }
                    path.pop_back();
                }
            }else{
                // 算出前两个数字的和,看对应的字符串是不是num的子串,不是的话返回,是的话往后搜索
                BigNum next_int = path[len-2] + path[len-1];
                string next_str = next_int.val;
                reverse(next_str.begin(), next_str.end());
                if(num.substr(pos, next_str.size()) == next_str){
                    path.push_back(next_int);
                    bool res = dfs(num, pos + next_str.size(), path);
                    path.pop_back();
                    return res;
                }else{
                    return false;
                }
            }
            return false;
        }
    };
    
    
  • 相关阅读:
    Xcode 环境下的汇编与 C/C++/ObjC (上)
    OpenGL ES的从地上爬起来,第1部分:
    Accessorizer的使用说明!
    我常用的iphone开发学习网站
    ruby+seleniumwebdriver一步一步完成自动化测试(2)—–一个测试用例
    Selenium Grid深入学习
    Seleniumwebdriver系列教程(14)————为firefox设置代理
    Seleniumwebdriver系列教程(15)————万能的截图
    Selenium Grid
    RSPEC入门学习
  • 原文地址:https://www.cnblogs.com/vinnson/p/13385395.html
Copyright © 2020-2023  润新知