topic:
Given a number string S, such as S = "123456579", we can divide it into Fibonacci-like sequences [123, 456, 579].
Formally, the Fibonacci sequence is a list F of non-negative integers and satisfies:
- 0 <= F[i] <= 2^31-1, (that is, each integer conforms to the 32-bit signed integer type);
- F.length >= 3;
- For all 0 <= i <F.length-2, F[i] + F[i+1] = F[i+2] holds.
In addition, please note that when splitting the string into small blocks, the number of each block must not start with a zero, unless the block is the number 0 itself.
Return any set of Fibonacci-like sequence blocks split from S, or [] if it cannot be split.
Example 1:
Input: "123456579"
Output: [123,456,579]
source:
842. Split the array into Fibonacci sequences
Problem-solving ideas: backtracking
Define a variable n to record the value of the string [start, i]. The for loop in the first recursion (start=0) is as follows:
- Recursive termination condition: digital string processing completed
- The result satisfies the condition: the digital string processing is completed, and the result is at least 3 numbers
- Pruning condition: After finding one, or the number exceeds the maximum value of int, or the Fibonacci formula is not satisfied (you can also add judgment: when the sum of the current two numbers is less than the current number n, exit the for loop, because the following number n Bigger)
class Solution {
public:
vector<int> result;
vector<int> path;
bool finish;
vector<int> splitIntoFibonacci(string S) {
finish = false;
// 处理开头的0
int start = 0;
while (start < S.size() && S[start] == '0') {
path.push_back(0);
start++;
}
back(S, start);
return result;
}
void back(const string& s, int start) {
if (path.size() > 2 && start == s.size()) {
finish = true;
result = path;
return;
}
long n = 0;
for (int i = start; i < s.size(); i++) {
if (finish) break;
n = n * 10 + s[i] - '0'; // n:[start,i]内的数字
if (n > 0x7fffffff) break;
int sz = path.size();
if (sz < 2 || (long)path[sz-1] + (long)path[sz-2] == n) {
path.push_back(n);
back(s, i + 1);
path.pop_back();
}
}
}
};
The number of each block must not start with a zero. If this situation is not handled, it can actually pass. For example: 11203 should return [], but this code returns [1,1,2,3].
The remedy is to add a line after int sz = path.size();: if (sz> 1 && s[start] == '0') break; means that when the sequence is at least 2 numbers, start is The number pointed to cannot be 0, if it is 0, skip it.