1. 程式人生 > 實用技巧 >【Leetcode每日一題】842. 將陣列拆分成斐波那契序列

【Leetcode每日一題】842. 將陣列拆分成斐波那契序列

寫了好久終於寫出來了

給定一個數字字串 S,比如 S = "123456579",我們可以將它分成斐波那契式的序列 [123, 456, 579]。

形式上,斐波那契式序列是一個非負整數列表 F,且滿足:

0 <= F[i] <= 2^31 - 1,(也就是說,每個整數都符合 32 位有符號整數型別);
F.length >= 3;
對於所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。
另外,請注意,將字串拆分成小塊時,每個塊的數字一定不要以零開頭,除非這個塊是數字 0 本身。

返回從 S 拆分出來的任意一組斐波那契式的序列塊,如果不能拆分則返回 []。

示例 1:

輸入:"123456579"
輸出:[123,456,579]
示例 2:

輸入: "11235813"
輸出: [1,1,2,3,5,8,13]
示例 3:

輸入: "112358130"
輸出: []
解釋: 這項任務無法完成。
示例 4:

輸入:"0123"
輸出:[]
解釋:每個塊的數字不能以零開頭,因此 "01","2","3" 不是有效答案。
示例 5:

輸入: "1101111"
輸出: [110, 1, 111]
解釋: 輸出 [11,0,11,11] 也同樣被接受。

提示:

1 <= S.length <= 200
字串 S 中只含有數字。

來源:力扣(LeetCode)
連結:

https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

class Solution {
public:
    vector<int> ans;

    static int string2int(const string &s, int start, int end) {
        string tmp = s.substr(start, end - start + 1);
        if (tmp.length() > 10) return -1;
        long long tmp_number = stoll(tmp);
        if (tmp_number > INT_MAX) return -1;
        return int(tmp_number);
    }

    void dfs(const string &s, int start, int end, bool &isOK, int &now_int) {
        isOK = false;
        //如果出現前導0,終止跳出
        if (start != end && s[start] == '0') return;
        now_int = string2int(s, start, end);
        //如果now_int溢位,終止跳出
        if (now_int == -1) return;
        //如果now_int恰好等於int_max
        if (now_int == INT_MAX && end != s.length() - 1) return;
        ans.push_back(now_int);
        if (ans.size() >= 3) {
            int a = *(ans.rbegin()), b = *(ans.rbegin() + 1), c = *(ans.rbegin() + 2);
            if ((long long) b + (long long) b > INT_MAX || c + b != a) {
                ans.pop_back();
                //如果當前以及分好,那麼則需要連pop兩個
                if (end == s.length() - 1) ans.pop_back();
                return;
            }
        }
        if (end == s.length() - 1) {
            if (ans.size() < 3) {
                ans.pop_back();
                return;
            } else {
                isOK = true;
                return;
            }
        }

        for (int i = end + 1; i < s.length(); ++i) {
            if (now_int == -1) {
                now_int = 0;
                ans.pop_back();
                return;
            }
            if (end + 1 != i && s[end + 1] == '0') {
                ans.pop_back();
                return;
            }
            dfs(s, end + 1, i, isOK, now_int);

            if (isOK) return;
        }
    }

    vector<int> splitIntoFibonacci(string S) {
        for (int i = 0; i < S.length(); ++i) {
            ans.clear();
            bool isOK = false;
            int now_int = 0;
            dfs(S, 0, i, isOK, now_int);
            if (isOK) break;
        }
        return ans;
    }
};

這裡的剪枝比較重要