题目
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.
答案
Typical backtracking problem, but need to pay attention to lots of details.
class Solution {
public List<Integer> splitIntoFibonacci(String S) {
List<Integer> list = new ArrayList<>();
recur(S, 0, list);
return list;
}
public boolean recur(String S, int curr_pos, List<Integer> list) {
if(list.size() >= 3 && curr_pos == S.length()) return true;
String max_int = Integer.toString(Integer.MAX_VALUE);
// choose anything for current choice
for(int i = curr_pos; i < S.length(); i++) {
String choice = S.substring(curr_pos, i + 1);
// Leading 0 is not allowed
if(choice.charAt(0) == '0' && choice.length() > 1) continue;
// Chec if choice can fit into an Integer object
if(choice.length() > max_int.length() || (choice.length() == max_int.length() && (choice.compareTo(max_int)) > 0)) continue;
int choice_int = Integer.parseInt(choice);
int curr_size = list.size();
if(curr_size <= 1) {
list.add(choice_int);
}
else {
int prev_sum = list.get(curr_size - 1) + list.get(curr_size - 2);
if(prev_sum == choice_int) {
list.add(choice_int);
}
else if(prev_sum > choice_int){
continue;
}
else {
break;
}
}
if(recur(S, i + 1, list)) return true;
list.remove(list.size() - 1);
}
return false;
}
}