LeetCode-306 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.

题目大意

字符串中包含‘0’-‘9’的数字,要求判断该数字字符串是否是可加序列。

(可加序列:前两个数字相加等于后一个数字,字符串中的所有数字均满足这个规则)

(PS:数字不会包含前缀‘0’,如‘02’或‘03’等,但会包含后缀‘0’,如‘200’等。此外,输入的数字可能会很大,超过long long)

示例

E1

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

E2

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

解题思路

外循环取出两个可能的数字,将数字送入内部递归函数,递归函数内将输入的两个数字相加,并判断是否与后续数字相等,若相等则继续递归,否则返回外层循环从新输入两个数字。

复杂度分析

时间复杂度:O(N2)

空间复杂度:O(N)

代码

class Solution {
public:
    bool isAdditiveNumber(string num) {
        // 遍历数字字符串,将两个数字依次输入递归函数
        for(int i = 1; i <= (num.length() / 2); ++i) {
            for(int j = 1; j <= (num.length() - i) / 2; ++j) {
                if(solve(num.substr(0, i), num.substr(i, j), num.substr(i + j)))
                    return true;
            }
        }
        
        return false;
    }
    
    bool solve(string s1, string s2, string num) {
        // 如果两个数字其中有一个包含前缀0,则返回false
        if((s1.length() > 1 && s1[0] == '0') || (s2.length() > 1 && s2[0] == '0'))
            return false;
        // 计算两个数字之和
        string sum = add(s1, s2);
        // 如果两个数字之和与剩余的字符串数字相等,则返回true
        if(sum == num)
            return true;
        // 否则,如果两个数字之和与后续字符串数字不匹配则返回false
        if(sum.length() >= num.length() || sum.compare(num.substr(0, sum.length())) != 0)
            return false;
        // 除了以上各个情况,进入下一层递归
        else
            return solve(s2, sum, num.substr(sum.size()));
    }
    // 计算两个字符串数字的和
    string add(string s1, string s2) {
        string res = "";
        int i = s1.length() - 1, j = s2.length() - 1, carry = 0;
        while(i >= 0 || j >= 0) {
            int x = carry + (i >= 0 ? s1[i--] - '0' : 0) + (j >= 0 ? s2[j--] - '0' : 0);
            res.push_back('0' + x % 10);
            carry = x / 10;
        }
        if(carry)
            res.push_back('0' + 1);
        reverse(res.begin(), res.end());
        
        return res;
    }
};
原文地址:https://www.cnblogs.com/heyn1/p/11163743.html