[Swift]LeetCode842. 將數組拆分紅斐波那契序列 | Split Array into Fibonacci Sequence

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-ygmazdrm-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

Given a string S of digits, such as S = "123456579", we can split it into a Fibonacci-like sequence [123, 456, 579].git

Formally, a Fibonacci-like sequence is a list F of non-negative integers such that:github

  • 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:app

Input: "123456579"
Output: [123,456,579]

Example 2:spa

Input: "11235813"
Output: [1,1,2,3,5,8,13]

Example 3:code

Input: "112358130"
Output: []
Explanation: The task is impossible.

Example 4:orm

Input: "0123"
Output: []
Explanation: Leading zeroes are not allowed, so "01", "2", "3" is not valid.

Example 5:htm

Input: "1101111"
Output: [110, 1, 111]
Explanation: The output [11, 0, 11, 11] would also be accepted.

Note:

  1. 1 <= S.length <= 200
  2. 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:

輸入:"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. 1 <= S.length <= 200
  2. 字符串 S 中只含有數字。

8ms

 1 class Solution {
 2     fileprivate var res = [Int]()
 3     fileprivate var maxVal = Int(pow(2.0,31.0)-1)
 4     fileprivate var found = false
 5     
 6     func splitIntoFibonacci(_ S: String) -> [Int] {
 7         guard S.count >= 3 else {
 8             return [Int]()
 9         }
10         
11         var S = S.characters.map{Int(String($0))!}
12         
13         findSequence(S)
14         return found ? res : [Int]()
15     }
16     
17     func findSequence(_ S: [Int], _ from: Int = 0){
18         if from >= S.count && res.count >= 3{
19             found = true
20             return
21         }
22     
23         var current = 0
24         for i in from..<S.count{
25             current *= 10
26             current += S[i]
27             guard current < maxVal else{
28                 return
29             }
30             
31             if i - from >= 1 && current < 10{
32                 return
33             }
34             
35             if isFibSeq(current){
36                 findSequence(S, i + 1)
37                 if found{
38                     return
39                 }
40                 res.remove(at: res.count - 1)
41             }
42         }
43     }
44     
45     func isFibSeq(_ num: Int)->Bool{
46         let count = res.count
47         if count < 2{
48             res.append(num)
49             return true
50         }
51         
52         if res[count - 1] + res[count - 2] == num{
53             res.append(num)
54             return true
55         }
56         
57         return false
58     }
59 }

20ms

 1 private extension String {
 2     var leadingZero: Bool {
 3         guard self.count > 1 else {
 4             return false
 5         }
 6 
 7         if self[self.startIndex] == "0" {
 8             return true
 9         }
10 
11         return false
12     }
13 }
14 
15 /// 咱們將一個給定的字符串進行分割,分割成斐波那契數列
16 
17 class Solution {
18     var limit: Int = 2_147_483_647
19 
20     func splitIntoFibonacci(_ S: String) -> [Int] {
21         if S.count < 3 {
22             return []
23         }
24         var array: [String] = []
25 
26         for index in 1...(min(10, S.count - 2)) {
27             let firstString = String(S.prefix(index))
28 
29             let lastString = String(S.suffix(S.count - index))
30 
31             array.append(firstString)
32 
33             if firstString.leadingZero {
34                 return []
35             }
36 
37             if findSecondSecondString(String(lastString), list: &array) {
38                 return array.map({Int($0) ?? 0})
39             } else {
40                 array.removeAll()
41             }
42         }
43 
44         return []
45     }
46 
47     func findSecondSecondString(_ S: String, list: inout [String]) -> Bool {
48         if S.count  < 1 {
49             return false
50         }
51 
52         for index in 1...(min(10, S.count - 1)) {
53             let firstString = String(S.prefix(index))
54 
55             let lastString = String(S.suffix(S.count - index))
56 
57             list.append(firstString)
58 
59             if judgeStringCanUse(lastString, list: &list) {
60                 return true
61             } else {
62                 let keep = list[0]
63                 list.removeAll()
64                 list.append(keep)
65                 continue
66             }
67         }
68         return false
69     }
70 
71     func judgeStringCanUse(_ S: String, list: inout [String]) -> Bool {
72         if S.count == 0 && list.count > 2 {
73             return true
74         }
75 
76         let n = Int(list[list.count - 1]) ?? 0
77         let n1 = Int(list[list.count - 2]) ?? 0
78         let target = n + n1
79         guard n <= limit && n1 <= limit && target <= limit else {
80             return false
81         }
82 
83         let targetString = "\(n + n1)"
84 
85         let firstS = S.prefix(targetString.count)
86 
87         if firstS == targetString {
88             list.append(String(firstS))
89 
90             return judgeStringCanUse(String(S.suffix(S.count - firstS.count)), list: &list)
91         }
92 
93         return false
94     }
95 }

Runtime: 36 ms
Memory Usage: 21.8 MB
 1 class Solution {
 2     func splitIntoFibonacci(_ S: String) -> [Int] {
 3         var ans:[Int] = [Int]()
 4         var cur:[Int] = [Int]()
 5         if S.isEmpty {return ans}
 6         SFhelper(S,0,&cur,&ans)
 7         return ans
 8     }
 9     
10     func SFhelper(_ S:String,_ start:Int,_ cur:inout [Int],_ ans:inout [Int])
11     {
12         if !ans.isEmpty{return}
13         if start == S.count
14         {
15             if cur.count > 2 { ans += cur}
16             return
17         }
18         let N:Int = cur.count
19         var V:Int64 = 0
20         var arrS:[Character] = Array(S)
21         for i in start..<S.count
22         {
23             V = V * 10  +  Int64((arrS[i].ascii - 48))
24             if V > 2147483647 {break}
25             if N < 2
26             {
27                 cur.append(Int(V))
28                 SFhelper(S, i + 1, &cur, &ans)
29                 cur.popLast()
30             }
31             else
32             {
33                 let beforeSum:Int = cur[N - 1] + cur[N - 2]
34                 if beforeSum > V {continue}
35                 else if beforeSum < V {break}
36                 else
37                 {
38                     cur.append(Int(V))
39                     SFhelper(S, i + 1, &cur, &ans)
40                     cur.popLast()
41                 }
42             }
43              if V==0 {break}
44         }
45     }
46 }
47 
48 //Character擴展
49 extension Character
50 {
51     //Character轉ASCII整數值(定義小寫爲整數值)
52     var ascii: Int {
53         get {
54             return Int(self.unicodeScalars.first?.value ?? 0)
55         }
56     }
57 }

100ms

 1 class Solution {
 2     private var result: [Int] = []
 3     func splitIntoFibonacci(_ S: String) -> [Int] {
 4         split(Array(S), nil, nil, nil, 0, [])
 5         return result
 6     }
 7     
 8     private func split(_ s: [Character],
 9                        _ op1: Int?,
10                        _ op2: Int?,
11                        _ sum: Int?,
12                        _ start: Int,
13                        _ out: [Int]) -> Bool {
14         if start == s.count {
15             if op1 != nil && op2 != nil && sum != nil {
16                 result = out
17                 return true 
18             }
19             return false 
20         } else {
21             for i in start..<s.count {
22                  if i - start > 0 && s[start] == "0" { return false }
23                 if let num = String(s[start...i]).toInt() {
24                     if num > Int(pow(2.0, 31.0)) - 1 { return false }
25                     if op1 == nil {
26                         if split(s, num, op2, sum, i + 1, out + [num]) {
27                             return true 
28                         }
29                     } else if op2 == nil {
30                         if split(s, op1, num, sum, i + 1, out + [num]) {
31                             return true 
32                         }
33                     } else {
34                         if num - op1! == op2! {
35                             if split(s, op2, num, num, i + 1, out + [num]) {
36                                 return true 
37                             }
38                         }
39                     }
40                 }
41             }
42               return false
43         }
44     }
45 }
46 
47 extension String {
48     func toInt() -> Int? {
49         return Int(self)!
50     }
51 }

104ms

 1 class Solution {
 2     func splitIntoFibonacci(_ S: String) -> [Int] {
 3         var result = [Int]()
 4         var chars = Array(S)
 5         helper(&result, chars)
 6         return result
 7     }
 8     
 9     fileprivate func helper(_ res: inout [Int], _ chars: [Character]) -> Bool {
10         if res.count > 2 && chars.count == 0 {
11             return true
12         }
13         
14         for i in 0..<chars.count {
15             if chars[0] == "0" && i > 0 {
16                 break
17             }
18             
19             // Int("2147483647214748364")!
20             
21             guard let val = Int(String(chars[0...i])), val < Int32.max else {
22                 return false
23             }
24             
25             
26             let size = res.count
27             if size >= 2 && val > res[size - 1] + res[size - 2] {
28                 return false
29             }
30 
31             if size < 2 || val == res[size - 1] + res[size - 2] {
32                 res.append(val)
33                 if helper(&res, Array(chars[(i+1)...])) {
34                     return true
35                 }
36                 res.removeLast()
37             }
38         }
39         return false;
40     }
41 }
相關文章
相關標籤/搜索