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

给定一个数字字符串 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:

输入:"123456579"
输出:[123,456,579]
示例 2:

输入: "11235813"
输出: [1,1,2,3,5,8,13]
示例 3:

输入: "112358130"
输出: []
解释: 这项任务无法完成。
示例 4:

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

输入: "1101111"
输出: [110, 1, 111]
解释: 输出 [11,0,11,11] 也同样被接受。
提示:

1 <= S.length <= 200
字符串 S 中只含有数字。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

代码有点儿烂,做了好久,超过人数才5点几,真TM fuck。

下面代码耗时87ms

 1 public class Solution {
 2     private String s;
 3     private int len = -1;
 4     private List<Integer> res;
 5     private int e1;
 6     private int e2;
 7     private int e3;
 8 
 9     private String isContinue(int m,int n,int o){
10         String r = null;
11         String a = s.substring(m, n);
12         String b = s.substring(n, o);
13         if (a.length() > 10 || b.length() > 10)
14             return "";
15         long a0 = Long.parseLong(a);
16         long b0 = Long.parseLong(b);
17         if (a0 > 2147483647 || b0 > 2147483647)
18             return "";
19         e1 = (int)a0;
20         e2 = (int)b0;
21         if (a0+b0 > 2147483647)
22             return "";
23         e3 = (int)(a0+b0);
24         String c = String.valueOf(a0 + b0);
25         if (a.charAt(0)=='0' && a.length()!=1 || b.charAt(0)=='0' && b.length() != 1)
26             r = "";
27         else if (c.length() > len-o)
28             r = "";
29         else if (!s.substring(o,o+c.length()).equals(c))
30             r = "";
31         return (r != null) ? "" : c;
32     }
33 
34     private boolean helper(int m, int n, int o){
35         if (isContinue(m,n,o).equals("")){
36             return false;
37         }
38 
39         for (int i = n; i < len; i++) {
40             for (int j = i+1; j < len; j++) {
41                 String c = isContinue(m, i, j);
42                 if (c.equals(""))
43                     continue;
44                 if (s.substring(j,j+c.length()).equals(c)){
45                     if (c.length() > len-j)
46                         return false;
47 
48                     res.add(e1);
49 
50                     if (c.length() == len-j) {
51                         if (e2 == e1 || res.get(res.size()-1) != e2)
52                             res.add(e2);
53                         res.add(e3);
54                         return true;
55                     }
56                     if (helper(i, j, j+c.length()))
57                         return true;
58 
59                     res.remove(res.size()-1);
60                 }
61             }
62         }
63         return false;
64     }
65     public List<Integer> splitIntoFibonacci(String S) {
66         s = S;
67         len = s.length();
68         res = new ArrayList<>();
69 
70         for (int i = 1; i < len; i++) {
71             for (int j = i+1; j < len; j++) {
72                 if (helper(0,i,j))
73                     return res;
74             }
75         }
76         return res;
77     }
78 
79     public static void main(String[] args) {
80         List<Integer> integers = new Solution().splitIntoFibonacci("3611537383985343591834441270352104793375145479938855071433500231900737525076071514982402115895535257195564161509167334647108949738176284385285234123461518508746752631120827113919550237703163294909");
81         System.out.println("integers = " + integers);
82     }
83 }

 下面代码耗时336ms。越改越差劲。。。至少提供了另一种解法。。。

 1 public class Solution {
 2     private String s;
 3     private List<String> res = null;
 4     private int len = -1;
 5     private String last1,last2,next;
 6 
 7     private boolean ok(String str){
 8         if (str.length() > 10 || Long.parseLong(str) > Integer.MAX_VALUE)
 9             return false;
10         return true;
11     }
12 
13     private boolean helper(int begin, int end){
14         if (res.size() >= 2){
15             last1 = res.get(res.size()-2);
16             last2 = res.get(res.size()-1);
17             next = s.substring(begin, end);
18 
19             if (!ok(last1) || !ok(last2) || !ok(next) || !ok(String.valueOf(Integer.parseInt(last1)+ Integer.parseInt(last2))))
20                 return false;
21             if (Integer.parseInt(last1) + Integer.parseInt(last2) == Integer.parseInt(next)) {
22                 if (next.charAt(0)=='0'&&next.length()>1)
23                     return false;
24                 res.add(next);
25             } else {
26                 return false;
27             }
28             if (end == len)
29                 return true;
30         } else {
31             String last = s.substring(begin, end);
32             if (last.charAt(0)=='0' && last.length()>1)
33                 return false;
34             res.add(last);
35         }
36         // end不是合适的划分位置
37         for (int i = 1; i < len;++i) {
38             if (end+i > len)
39                 break;
40             if (helper(end, end+i))
41                 return true;
42         }
43         res.remove(res.size()-1);
44         return false;
45     }
46 
47     public List<Integer> splitIntoFibonacci(String S) {
48         s = S;
49         res = new ArrayList<>();
50         len = s.length();
51         for (int i = 1; i < len; i++) {
52             if (helper(0,i))
53                 break;
54         }
55         List<Integer> r = new ArrayList<>();
56         for (String s : res) {
57             r.add(Integer.parseInt(s));
58         }
59         return r;
60     }
61 
62 
63     public static void main(String[] args) {
64         List<Integer> integers = new Solution().splitIntoFibonacci("112358130");
65         System.out.println("integers = " + integers);
66     }
67 }

 终于找到原因了,string.substring()是一个很耗时的操作,把每一个字符串转化整数后,存储起来供后续使用,能极大提高效率。。。下面代码大约15-35ms之间。

 1 public class Solution {
 2     private String s;
 3     private List<Integer> res = null;
 4     private int len = -1;
 5     private int last1,last2;
 6     private String next;
 7     private long[][] memory = null;
 8 
 9     private boolean helper(int begin, int end){
10         if (res.size() >= 2){
11             last1 = res.get(res.size()-2);
12             last2 = res.get(res.size()-1);
13             next = s.substring(begin, end);
14             if (next.length() <= 10 && memory[begin][end] == 0)
15                 memory[begin][end] = Long.parseLong(next);
16             if (next.charAt(0)=='0'&&next.length()>1 || next.length() > 10 || memory[begin][end] > Integer.MAX_VALUE)
17                 return false;
18 
19             if (last1 + last2 == memory[begin][end]) { // memory[begin][end]存储的就是next
20                 res.add((int)memory[begin][end]);
21             } else {
22                 return false;
23             }
24             if (end == len)
25                 return true;
26         } else {
27             if (memory[begin][end] == 0) {
28                 String last = s.substring(begin, end);
29                 if (last.length() > 10 || memory[begin][end] > Integer.MAX_VALUE)
30                     return false;
31                 memory[begin][end] = Long.parseLong(last);
32                 if (last.charAt(0)=='0' && last.length()>1)
33                     return false;
34             }
35             res.add((int)memory[begin][end]);
36         }
37         // end不是合适的划分位置
38         for (int i = 1; i < len;++i) {
39             if (end+i > len)
40                 break;
41 
42             if (helper(end, end+i))
43                 return true;
44         }
45         res.remove(res.size()-1);
46         return false;
47     }
48 
49     public List<Integer> splitIntoFibonacci(String S) {
50         s = S;
51         res = new ArrayList<>();
52         len = s.length();
53         memory = new long[len+1][len+1];
54         for (int i = 1; i < len; i++) {
55             if (helper(0,i))
56                 break;
57         }
58         return res;
59     }
60 
61     public static void main(String[] args) {
62         List<Integer> integers = new Solution().splitIntoFibonacci("214748364721474836422147483641");
63         System.out.println("integers = " + integers);
64     }
65 }

 

posted @ 2019-10-03 22:06  赤云封天  阅读(625)  评论(0编辑  收藏  举报