Leetcode之Split Array into Fibonacci Sequence

題目:

Given a string S of digits, such as S = "123456579", we can split it into a Fibonacci-like sequence [123, 456, 579].

Formally, a Fibonacci-like sequence is a list F of non-negative integers such that:

  • 0 <= F[i] <= 2^31 - 1, (that is, each integer fits a 32-bit signed integer type);
  • F.length >= 3;
  • and F[i] + F[i+1] = F[i+2] for all 0 <= i < F.length - 2.

Also, note that when splitting the string into pieces, each piece must not have extra leading zeroes, except if the piece is the number 0 itself.

Return any Fibonacci-like sequence split from S, or return [] if it cannot be done.

Example 1:

Input: "123456579"
Output: [123,456,579]

Example 2:

Input: "11235813"
Output: [1,1,2,3,5,8,13]

Example 3:

Input: "112358130"
Output: []
Explanation: The task is impossible.

Example 4:

Input: "0123"
Output: []
Explanation: Leading zeroes are not allowed, so "01", "2", "3" is not valid.

Example 5:

Input: "1101111"
Output: [110, 1, 111]
Explanation: The output [11, 0, 11, 11] would also be accepted.

Note:

  1. 1 <= S.length <= 200
  2. S contains only digits.

代碼:

方法一——暴力搜索法:

class Solution {
public:
    vector<int> splitIntoFibonacci(string S) {
        int len = S.length(); vector<int> v;
    for (int i = 1; i < 10; i++) {
        for (int j = 1; j <=10; j++) {
            v.clear();
            string s1 = S.substr(0, i);
            if (i != 1 && s1[0] == '0')continue;
            string s2 = S.substr(i, j);
            if (j != 1 && s2[0] == '0')continue;
            string temp = S.substr(i + j);
            long i1 = atol(s1.c_str());  v.push_back((int)i1);
            long i2 = atol(s2.c_str()); v.push_back((int)i2);
            long i3 = i1 + i2;
            string s3 = to_string(i3);
            while (temp.substr(0, s3.length()) == s3) {
                if(i3>INT_MAX)break;
                i3=(int)i3;
                v.push_back(i3);
                temp = temp.substr(s3.length());
                if (temp == "")break;
                i1 = i2; i2 = i3;
                i3 = i1 + i2;
                s3 = to_string(i3);
            }
            if (temp == "")return v;            
        }
    }
    return {};
    }
};

想法:暴力,考慮數據溢出long的情況

方法二——回溯法:

class Solution {
public:

    bool backtrack(string &S, int start, vector<int> &nums){        
        int n = S.size();
	// If we reached end of string & we have more than 2 elements
	// in our sequence then return true
        if(start >= n && nums.size()>=3){
            return true;
        }
	// Since '0' in beginning is not allowed therefore if the current char is '0'
	// then we can use it alone only and cannot extend it by adding more chars at the back.
	// Otherwise we make take upto 10 chars (length of INT_MAX)
        int maxSplitSize = (S[start]=='0') ? 1 : 10;
	// Try getting a solution by forming a number with 'i' chars begginning with 'start'
        for(int i=1; i<=maxSplitSize && start+i<=S.size(); i++){
            long long num = stoll(S.substr(start, i));
            if(num > INT_MAX)
                return false;
            int sz = nums.size();
	// If fibonacci property is not satisfied then we cannot get a solution
            if(sz >= 2 && nums[sz-1]+nums[sz-2] < num)
                return false;
            if(sz<=1 || nums[sz-1]+nums[sz-2]==num){
                nums.push_back(num);
                if(backtrack(S, start+i, nums))
                    return true;
                nums.pop_back();                
            }
        }
        return false;
    }
    
    vector<int> splitIntoFibonacci(string S) {
        vector<int> nums;
	// Backtrack from 0th char
        backtrack(S, 0, nums);
        return nums;
    }
};

思路:調用一個回溯的函數,路徑中保存每一步產生的nums,對nums.size=0和=1的情況分類討論,對開頭爲0和不爲0的情況分類討論,對是否溢出的情況分類討論。

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