题目说明
累加数 是一个字符串,组成它的数字可以形成累加序列。
一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。
给你一个只包含数字 ‘0’-‘9’ 的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回 true ;否则,返回 false 。
说明:累加序列里的数 不会 以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。
提示:
1 <= num.length <= 35
num 仅由数字(0 - 9)组成
示例
示例 1:
1 2 3
| 输入:"112358" 输出:true 解释:累加序列为: 1, 1, 2, 3, 5, 8 。1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
|
示例 2:
1 2 3
| 输入:"199100199" 输出:true 解释:累加序列为: 1, 99, 100, 199。1 + 99 = 100, 99 + 100 = 199
|
笔者理解
此题是一道字符串算法问题,在力扣题库中被定义为中等题。
解法
当笔者阅读完此题后,发现此题考察的其实就是深度优先搜索的能力和剪枝的判断,让我们来看看具体如何实现的吧。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| import java.math.BigInteger;
class Solution {
public boolean isAdditiveNumber(String num) { int size = num.length();
int firstSize = 1;
while (firstSize < size - 1) { String first = num.substring(0, firstSize); if (judge(first)) { break; }
BigInteger firstNum = new BigInteger(first);
for (int i = 1; i <= (size - firstSize) / 2; i++) { String second = num.substring(firstSize, firstSize + i); if (judge(second)) { continue; }
BigInteger secondNum = new BigInteger(second);
if (dfs(num.substring(firstSize + i, size), firstNum, secondNum, 2)) { return true; } }
firstSize++; }
return false; }
public boolean judge(String num) { return num.length() > 1 && num.charAt(0) == '0'; }
public boolean dfs (String num, BigInteger firstNum, BigInteger secondNum, int count) {
int size = num.length();
if (size == 0 && count >= 3) { return true; }
int bigSize = Math.max(firstNum.toString().length(), secondNum.toString().length());
if (size < bigSize) { return false; }
int length = Math.min(size, bigSize + 1);
for (int i = bigSize; i <= length; i++) { String third = num.substring(0, i); if (judge(third)) { continue; }
BigInteger thirdNum = new BigInteger(third);
if (firstNum.add(secondNum).equals(thirdNum)) { return dfs(num.substring(i, size), secondNum, thirdNum, count + 1); } }
return false; } }
|
时间、空间效率一般,可见此解法还比较适合此题。

总结
本题是今天的每日一题,难度是为中等,感兴趣的朋友都可以去尝试一下,此题还有其他更多的解法,朋友们可以自己逐一尝试。