1. 程式人生 > 其它 >【LeetCode】每日一題842. 將陣列拆分成斐波那契序列

【LeetCode】每日一題842. 將陣列拆分成斐波那契序列

技術標籤:每日一題javaleetcode遞迴演算法

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 中只含有數字。

解題思路:

沒做出來~,參考的官方解答。

本質上還是暴力解法,只是暴力的更優美~。使用「回溯」+「剪枝」大大提升了效率。解釋在程式碼註釋中。

方法一:回溯 + 剪枝

public List<Integer> splitIntoFibonacci(String S) {
    List<Integer> list = new ArrayList<>
(); backtrack(list, S, 0); return list; } public boolean backtrack(List<Integer> list, String S, int index) { // 遞迴終止條件,遍歷到末尾時,陣列長度必須大於等於3 if (index == S.length()) { return list.size() >= 3; } for (int i = index; i < S.length(); i++) { // 排除首位是 0 if (i > index && S.charAt(index) == '0') { break; } // 用long 接收,避免超過int 最大值 long longValue = Long.parseLong(S.substring(index, i + 1)); if (longValue > Integer.MAX_VALUE) { break; } int intValue = (int) longValue; // 陣列有兩個以上的元素時,當前值必須等於末尾兩個元素的和 if (list.size() >= 2) { int sum = list.get(list.size() - 1) + list.get(list.size() - 2); if (intValue < sum) { continue; } else if (intValue > sum) { break; } } list.add(intValue); // 繼續向下遞迴,失敗說明當前元素不存在解,刪除當前元素 if (!backtrack(list, S, i + 1)) { list.remove(list.size() - 1); } else { return true; } } return false; }

執行結果

在這裡插入圖片描述