zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Laravel5.0学习--03 Artisan命令
    yar框架使用笔记
    MySQL外键之级联
    笛卡尔积
    PHP钩子机制
    CentOS安装PHP7+Nginx+MySQL
    Linux压缩命令
    Git命令汇总
    使用List把一个长字符串分解成若干个短字符串
    Adb connection Error:远程主机强迫关闭了一个现有的连接
  • 原文地址:https://www.cnblogs.com/yfs123456/p/11620933.html
Copyright © 2011-2022 走看看