- 累加数
累加数是一个字符串,组成它的数字可以形成累加序列。
一个有效的累加序列必须至少包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。
给定一个只包含数字 ‘0’-‘9’ 的字符串,编写一个算法来判断给定输入是否是累加数。
说明: 累加序列里的数不会以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。
- 示例 1:
输入: “112358”
输出: true
解释: 累加序列为: 1, 1, 2, 3, 5, 8 。1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
- 示例 2:
输入: “199100199”
输出: true
解释: 累加序列为: 1, 99, 100, 199。1 + 99 = 100, 99 + 100 = 199
- 进阶:
你如何处理一个溢出的过大的整数输入?
来源:力扣(LeetCode)
# 逆向求解过程
class Solution:
def isAdditiveNumber(self, num):
length = len(num)
if length < 3:
return False
i = length - 1
if int(num[i]) == int(num[i-1]) + int(num[i-2]):
if i-2 == 0:
return True
else:
i -= 1
elif i-2 <= 0:
return False
else:
step = 1
while step <= (i // 2 ):
stepRst = self.find(num[:i-step], num[i-step:], i-step)
if stepRst:
i -= step
if stepRst[1] == 0:
return True
else:
break
else:
step += 1
if step >= (i // 2 ):
return False
return self.isAdditiveNumber(num[:i])
return self.isAdditiveNumber(num[:i+1])
def find(self, num, lastSum, length):
# if "0" in lastSum[0]:
# return False
sumLen = len(lastSum.strip())
lastSum = int(lastSum)
for i in range(length-1, -1, -1):
for j in range(i-1, -1, -1):
if len(num[i:]) > sumLen:
return False
if len(num[i:]) <= sumLen and len(num[j:i]) > sumLen:
break
if num[i:][0] == "0" or num[j:i][0] == "0":
continue
if int(num[j:i]) + int(num[i:]) == lastSum:
return (i, j)
if __name__ == "__main__":
print(Solution().isAdditiveNumber("112358"))
print(Solution().isAdditiveNumber("199100199"))
print(Solution().isAdditiveNumber("000"))
print(Solution().isAdditiveNumber("1203"))
print(Solution().isAdditiveNumber("0235813"))
print(Solution().isAdditiveNumber("211738"))
print(Solution().isAdditiveNumber("121224036"))
题解:
LeetCode 上测试用例 "1203"结果为 False, 与 “121224036” 为 True 矛盾。
- 通过递归缩小 nums 的范围;
- 模拟 step 获得可能的累加和;
- 贪心或暴力求累加组合;利用已知的条件,减少不必要的循环。