- 累加數
累加數是一個字符串,組成它的數字可以形成累加序列。
一個有效的累加序列必須至少包含 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 獲得可能的累加和;
- 貪心或暴力求累加組合;利用已知的條件,減少不必要的循環。