【LeetCode】842. Split Array into Fibonacci Sequence 将数组拆分成斐波那契序列(Medium)(JAVA)每日一题

【LeetCode】842. Split Array into Fibonacci Sequence 将数组拆分成斐波那契序列(Medium)(JAVA)

题目地址: https://leetcode.com/problems/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 <= S.length <= 200
  • S contains only digits.

题目大意

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

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

  • 0 <= F[i] <= 2^31 - 1,(也就是说,每个整数都符合 32 位有符号整数类型);
  • F.length >= 3;
  • 对于所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。

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

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

解题方法

  1. 首先要看清楚例子,将数组拆分成斐波那契序列:数组里的每个元素不一定是相等的
  2. 所以要从第一个数字长度 i 从 1 到 S.length() / 2,第二个长度 j 也从 1 到 S.length() / 2,因为要满足至少三个,而且三个数字肯定大于前两个数组所以, S.length() - i - j >= Math.max(i, j)
  3. 判断第三个是否是前两个的和,从 i + j 位开始,判断接下来的部分是否 num1 + num2 (我这里直接用的 string 的 startWith 方法,判断的方法很多)
  4. 后面不断循环,看是否能到能把所有字符判断完
  5. note: 这里还有很多可以优化的地方:1、可以不用创建新的字符串,这样可以节省空间,也不用 delete 字符;2、比较可以不用 startWith 方法,可以一个个 char 比较
class Solution {
    public List<Integer> splitIntoFibonacci(String S) {
        List<Integer> list = new ArrayList<>();
        int max = S.length() / 2;
        for (int i = 1; i <= max; i++) {
            long num = Long.parseLong(S.substring(0, i));
            if (num >= Integer.MAX_VALUE) break;
            if (S.charAt(0) == '0' && i > 1) continue;
            for (int j = 1; j <= max && (S.length() - i - j) >= Math.max(i, j); j++) {
                if (S.charAt(i) == '0' && j > 1) continue;
                StringBuilder sb = new StringBuilder(S);
                num = Long.parseLong(S.substring(0, i));
                list = new ArrayList<>();
                list.add((int) num);
                num = Long.parseLong(S.substring(i, i + j));
                if (num >= Integer.MAX_VALUE) break;
                list.add((int) num);
                sb.delete(0, i + j);
                while (sb.length() > 0) {
                    int size = list.size();
                    num = list.get(size - 1) + list.get(size - 2);
                    if (num >= Integer.MAX_VALUE) break;
                    if (!sb.toString().startsWith(num + "")) break;
                    list.add((int) num);
                    sb.delete(0, (num + "").length());
                }
                if (sb.length() == 0 && list.size() >= 3) return list;
            }
        }
        return new ArrayList<>();
    }
}

执行耗时:8 ms,击败了20.32% 的Java用户
内存消耗:38.7 MB,击败了66.05% 的Java用户

欢迎关注我的公众号,LeetCode 每日一题更新
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值