05 August 2008
Given a string
of digits, such as 1
S
, we can split it into a Fibonacci-like sequence 1
S = "123456579"
1
[123, 456, 579].
Formally, a Fibonacci-like sequence is a list
of non-negative integers such that:1
F
1
0 <= F[i] <= 2^31 - 1
, (that is, each integer fits a 32-bit signed integer type);1
F.length >= 3
;1
F[i] + F[i+1] = F[i+2]
for all 1
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
, or return 1
S
if it cannot be done.1
[]
Example 1:
1
2
Input: "123456579"
Output: [123,456,579]
Example 2:
1
2
Input: "11235813"
Output: [1,1,2,3,5,8,13]
Example 3:
1
2
3
Input: "112358130"
Output: []
Explanation: The task is impossible.
Example 4:
1
2
3
Input: "0123"
Output: []
Explanation: Leading zeroes are not allowed, so "01", "2", "3" is not valid.
Example 5:
1
2
3
Input: "1101111"
Output: [110, 1, 111]
Explanation: The output [11, 0, 11, 11] would also be accepted.
Note:
1
1 <= S.length <= 200
1
S
contains only digits.1
Integer.MAX_VALUE
1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Solution {
List<Integer> result;
public List<Integer> splitIntoFibonacci(String S) {
List<Integer> current = new ArrayList<>();
backtracking(current, S, 0, 0);
return result != null ? result : new ArrayList<>();
}
public void backtracking(List<Integer> current, String S, int prevIndex, int index) {
// 3. The sequence should has at least 3 elements
if( index == S.length() && current.size() > 2)
result = new ArrayList<>(current);
else{
for(int i = index; i < S.length(); i++) {
// 1. Remove elements with leading zero
if( S.charAt(prevIndex) == '0' && i + 1 - prevIndex > 1 )
break;
long longValue = Long.parseLong(S.substring(prevIndex, i + 1));
// 2. The element in the sequence should be at most Integer.MAX_VALUE
if( longValue > Integer.MAX_VALUE )
break;
int size = current.size();
if( current.size() < 2 ) {
current.add((int) longValue);
backtracking(current, S, i + 1, i + 1);
// 5. If we find a valid sequence, stop backtracking
if( result != null )
break;
current.remove(current.size() - 1);
}
else{
long sum = (long)current.get(size - 1) + (long)current.get(size - 2);
// 4. If current number is larger than the sum of previous two elements, stop backtracking
if( longValue > sum )
break;
else if( longValue < sum )
continue;
else {
current.add((int) longValue);
backtracking(current, S, i + 1, i + 1);
if( result != null )
break;
current.remove(current.size() - 1);
}
}
}
}
}
}
另外一个思路
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public List<Integer> splitIntoFibonacci(String S) {
List<Integer> result = new ArrayList<>();
backtracking(S, result, 0);
return result;
}
public boolean backtracking(String s, List<Integer> result, int index1) {
if (index1 == s.length() && result.size() >= 3) { // 结果集中至少3个数
return true;
}
for (int index2 = index1; index2 < s.length(); index2++) { // 从当前index开始直到末尾
if (s.charAt(index1) == '0' && index2 > index1) { //当前数字为0,且不在第一个位置
break;
}
long num = Long.parseLong(s.substring(index1, index2 + 1));
if (num > Integer.MAX_VALUE) {
break;
}
int size = result.size();
// early termination
if (size >= 2 && num > result.get(size - 1) + result.get(size - 2)) {
break;
}
if (size <= 1 || num == result.get(size - 1) + result.get(size - 2)) {
result.add((int) num);
// branch pruning. if one branch has found fib seq, return true to upper call
if (backtracking(s, result, index2 + 1)) {
return true;
}
result.remove(result.size() - 1);
}
}
return false;
}
}