友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

842. 将数组拆分成斐波那契序列

给定一个数字字符串 num,比如 123456579,我们可以将它分成「斐波那契式」的序列 [123, 456, 579]

形式上,斐波那契式序列是一个非负整数列表 f,且满足:

  • 0 <= f[i] < 231 ,(也就是说,每个整数都符合 32 位 有符号整数类型)

  • f.length >= 3

  • 对于所有的 0 <= i < f.length - 2,都有 f[i] + f[i + 1] = f[i + 2]

另外,请注意,将字符串拆分成小块时,每个块的数字一定不要以零开头,除非这个块是数字 0 本身。

返回从 num 拆分出来的任意一组斐波那契式的序列块,如果不能拆分则返回 []

示例 1:

输入:num = "1101111"
输出:[11,0,11,11]
解释:输出 [110,1,111] 也可以。

示例 2:

输入: num = "112358130"
输出: []
解释: 无法拆分。

示例 3:

输入:"0123"
输出:[]
解释:每个块的数字不能以零开头,因此 "01","2","3" 不是有效答案。

提示:

  • 1 <= num.length <= 200

  • num 中只含有数字

思路分析

回溯+剪枝:将字符串分割成数字,逐个检查是否可以组成斐波那契数列,不符合要求就回溯。

0842 10
  • 一刷

 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
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2026-07-31 22:25:24
 */
public List<Integer> splitIntoFibonacci(String num) {
  List<Integer> result = new ArrayList<>();
  if (backtrack(result, num, 0) && result.size() > 2) {
    return result;
  }
  return Collections.emptyList();
}

private boolean backtrack(List<Integer> result, String num, int index) {
  if (index == num.length()) {
    return true;
  }
  for (int i = 1; i < Math.min(num.length() / 2 + 1, 11); i++) {
    int next = index + i;
    if (i > 1 && num.charAt(index) == '0') {
      return false;
    }
    long lc = Long.parseLong(num.substring(index, Math.min(num.length(), next)));
    if (lc > Integer.MAX_VALUE) {
      return false;
    }
    int curr = (int) lc;
    if (result.size() < 2) {
      result.add(curr);
      if (backtrack(result, num, next)) {
        return true;
      } else {
        result.removeLast();
      }
    } else {
      if (result.get(result.size() - 2) + result.getLast() == curr) {
        result.add(curr);
        if (backtrack(result, num, next)) {
          return true;
        } else {
          result.removeLast();
        }
      }
      if (result.get(result.size() - 2) + result.getLast() < curr) {
        return false;
      }
    }
  }
  return false;
}