1. 程式人生 > >[leetcode] 306. Additive Number

[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.

For example:
“112358” is an additive number because 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
“199100199” is also an additive number, the additive sequence is: 1, 99, 100, 199.
1 + 99 = 100, 99 + 100 = 199
Note: Numbers in the additive sequence cannot have leading zeros, so sequence 1, 2, 03 or 1, 02, 3 is invalid.

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

Follow up:
How would you handle overflow for very large input integers?
題意:
定義Additive數字,最少包含三個數字,除了前兩個數字外,其他數字都是滿足是前兩個數字的和。給一個字串,裡面都是0-9,數字不能以0開始,比如03。現在給一個字串你,判斷下這個字串是不是Additive數字。
思路:
除了第一個數字和第二個數字可以改變外,後面的數字都是由前兩個數字決定的。所以回溯只需要回溯前面兩個數字,第一個數字可以是num陣列的前1…n/2數字組成的數字,第二個數字可以是從前一個字串的下一個位置開始到倒數第二個位置。然後把這兩個字串相加得到第三個字串,檢視接下來的子串是不是等於剛才那兩個字串的和。所以我們還需要實現一個字串的加法(順便處理了下 大數問題)。
程式碼如下:

class Solution {
public:
    bool isAdditiveNumber(string num) {
        if(num.length() <= 2)return false;
        return backTracking(num, "", "", 0);
    }
    bool backTracking(string& num, string s1, string s2, int index) {
        if(s1 == "") {
            for(int i = 0; i <= num.length() / 2; i++) {
                auto res = backTracking(num, num.substr(0, i + 1), s2, i + 1);
                if(res)return true;
            }
        }
        else if(s2 == "") {
            for(int i = index; i < num.length() - 1; i++) {
                auto res = backTracking(num, s1, num.substr(index, i - index + 1), i + 1);
                if(res)return true;
            }
        }
        else {
            if(index == num.length())return true;
            auto sum = add(s1, s2);
            if(num[index] == '0' || num.length() - index < sum.length() || sum != num.substr(index, sum.length()))return false;
            return backTracking(num, s2, sum, index + sum.length());
        }
    }
    string add(string s1, string s2) {
        int len1 = s1.length();
        int len2 = s2.length();
        if(len1 == 0)return s2;
        else if(len2 == 0)return s1;
        int carry = 0;
        int length = (len1 > len2)?len1:len2;
        string result(length, '0');
        char c1, c2;
        len1--,len2--,length--;
        for(; len1 >= 0 || len2 >= 0; len1--, len2--, length--) {
            if(len1 < 0)c1 = '0';
            else c1 = s1[len1];
            if(len2 < 0)c2 = '0';
            else c2 = s2[len2];
            int res = c1 + c2 - 2*'0' + carry;
            carry = res/10;
            res = res%10;
            result[length] = '0' + res;
        }
        if(carry == 1)return "1" + result;
        else return result;
    }
};