Leetcode306. Additive Number累加数

累加数是一个字符串,组成它的数字可以形成累加序列。

一个有效的累加序列必须至少包含 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

 

题不难,但是坑很多。

1.怎么处理溢出过大的数

2.遇到0怎么处理

3.如何优化

 

将字符串分成多个数,存在数组中,最后进行判断

class Solution
{
    string strllmax;

  public:
    bool isAdditiveNumber(string num)
    {
        strllmax = to_string(__LONG_LONG_MAX__);
        vector<long long> v;
        return DFS(0, num, v);
    }

    bool DFS(int pos, string num, vector<long long> &nums)
    {
        if (pos >= num.size())
        {
            //check
            if (nums.size() <= 2)
                return false;

            for (int i = 2; i < nums.size(); i++)
            {
                if (nums[i] != nums[i - 1] + nums[i - 2])
                    return false;
            }
            return true;
        }
        long long temp = 0;
        for (int i = pos; i < num.size(); i++)
        {
            //new1
            if (num[i] == 0 && i > 1)
                break;
            string str = num.substr(pos, (i - pos + 1));
            if (str.size() > strllmax.size() || str.size() == strllmax.size() && str > strllmax)
                break;
            temp = temp * 10 + num[i] - '0';
            nums.push_back(temp);
            if (DFS(i + 1, num, nums))
            {
                return true;
            }
            else
            {
                nums.pop_back();
            }
            if (temp == 0)
                break;
        }
        return false;
    }
};

上面版本的优化版

class Solution
{
  public:
    string long_max;
    bool isAdditiveNumber(string num)
    {
        vector<long long> nums;
        long_max = to_string(__LONG_LONG_MAX__);
        return DFS(nums, num, 0, num.size());
    }
    bool isvalid(vector<long long> &nums)
    {
        if (nums.size() < 3)
            return false;
        for (int i = 2; i < nums.size(); i++)
        {
            long long a = nums[i - 2];
            long long b = nums[i - 1];
            long long c = nums[i];
            if (a + b != c)
                return false;
        }
        return true;
    }
    bool DFS(vector<long long> &nums, string &str, int pos, int N)
    {
        if (pos == N)
        {
            return isvalid(nums);
        }
        for (int i = 1; i <= N - pos; i++)
        {
            if (str[pos] == '0' && i > 1)
                break;
            string sub = str.substr(pos, i);
            if (sub.size() > long_max.size() || sub.size() == long_max.size() && sub.compare(long_max) > 0)
                break;
            nums.push_back(stoll(sub));
            if ((nums.size() > 2 && !isvalid(nums)) || !DFS(nums, str, pos + i, N))
            {
                nums.pop_back();
            }
            else
            {
                return true;
            }
        }
        return false;
    }
};

最好的写法:

class Solution
{
  public:
    bool isAdditiveNumber(string num)
    {
        for (int i = 1; i <= num.size() / 2; i++)
            for (int j = 1; j <= (num.size() - i) / 2; j++)
                if (check(num.substr(0, i), num.substr(i, j), num.substr(i + j)))
                    return true;
        return false;
    }

  private:
    bool check(string num1, string num2, string num)
    {
        if ((num1.size() > 1 && num1[0] == '0') or (num2.size() > 1 && num2[0] == '0'))
            return false;
        auto sum = add(num1, num2);
        if (sum == num)
            return true;
        if (num.size() <= sum.size() or sum != num.substr(0, sum.size()))
            return false;
        else
            return check(num2, sum, num.substr(sum.size()));
    }
    string add(string s1, string s2)
    {
        string res;
        int carry(0);
        int i(s1.size() - 1), j(s2.size() - 1);
        while (i >= 0 || j >= 0)
        {
            int sum = carry + ((i >= 0) ? (s1[i--] - '0') : 0) + ((j >= 0) ? (s2[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;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值