leetcode306-累加數

給定一個只包含數字 ‘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、如何劃分數字?

每次驗證前兩個數之和時,需要先確定這兩個數,可是我們事先並不知道數字有多長,也不確定第二個數字的起始位置,於是要做的是:

  • 確定第一個數字的長度len1
  • 如此一來,第二個數字起始位置就確定下來了
  • 接着確定其長度爲len2
  • 於是需要驗證的數字的起始位置也確定了,其長度與前兩數之和的長度一致

通過上述4個步驟,可以確定一次驗證結果,此時分爲兩種情況:

(1)驗證成功

驗證成功時,可以進入下一輪次驗證:

  • 將數字往前挪動一位,即:之前的第二個數字變爲第一個數字
  • 原本驗證成功的數字變爲第二個數字
  • 此時前兩位數字已經確定下來了,於是第三個數字的首位可以確定
  • 又因爲前兩個數字已經確定,其和也能很快計算出來,第三個數字的長度也就確定了

這就像骨諾米牌一樣,一旦第一輪中的某次驗證匹配了,剩下的輪次就不需要劃分數字,直接匹配下去直到成功或者失敗

(2)驗證失敗

這次驗證失敗並不代表本輪匹配失敗,可以考慮增加第一個數字或者是第二個數字的長度,再參與比較驗證,準確的說,就是我們需要遍歷所有可能的組合,當所有的組合都失敗了,我們才能說這一輪次匹配失敗,結果返回false

2、大數相加問題

採用字符串加法,從末位加起

3、怎麼樣才能遍歷所有的可能組合?

這個問題纔是本題的關鍵所在,我們如何遍歷所有可能的組合?

根據之前的分析,我們只需要找出第一輪中的所有組合即可,因爲在第一輪中出現匹配之後,可以通過遞歸來確定,該配對是否成功。

C++代碼:

class Solution {
public:
    bool isAdditiveNumber(string num) {
        int i1 = 0, len = num.size();
        bool flag = false;
         for(int len1=1; len1 < len; len1++){
            string s1 = num.substr(i1, len1);
            if(s1[0] == '0' && len1 > 1)
                break;
            for(int len2=1; len2 < len; len2++){
                int i2 = i1 + len1;
                string s2 = num.substr(i2, len2);
                if(s2[0] == '0' && len2 > 1)
                    break;
                string sum = addString(s1, s2);
                int len3 = sum.size(), i3 = i2 + len2;
                if(i3 + len3 > num.size())
                    break;
                string s3 = num.substr(i3, len3);
                if(sum == s3){
                    flag = dfs(num, s2, s3, i3 + len3);
                }
                if(flag)
                    return flag;
            }
        }       
        return false;
    }

    bool dfs(string& num, string& s1, string& s2, int i3){
        if(i3 == num.size())
            return true;
        string sum = addString(s1, s2);
        int len3 = sum.size();
        if(i3 + len3 > num.size())
            return false;
        string s3 = num.substr(i3, len3);
        if(s3 == sum)
            return dfs(num, s2, s3, i3 + len3);
        else
            return false;
    }

    string addString(string& s1, string& s2){
        string ans;
        int i = s1.size() - 1, j = s2.size() - 1;
        int carry = 0, p;
        while(i >= 0 && j >= 0){
            int t1 = s1[i] - '0', t2 = s2[j] - '0';
            int temp = t1 + t2 + carry;
            carry = temp / 10;
            p = temp % 10;
            char ch = p + '0';
            ans = ch + ans;
            i--;
            j--;
        }
        while(i >= 0){
            int t1 = s1[i] - '0';
            int temp = t1 + carry;
            carry = temp / 10;
            p = temp % 10;
            char ch = p + '0';
            ans = ch + ans;
            i--;
        }
        while(j >= 0){
            int t2 = s2[j] - '0';
            int temp = t2 + carry;
            carry = temp / 10;
            p = temp % 10;
            char ch = p + '0';
            ans = ch + ans;
            j--;
        }
        if(carry){
            char ch = carry + '0';
            ans = ch + ans;
        }
        return ans;
    }
};

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章