LeetCode Daily Question: 306. Cumulative Number

  1. Cumulative number

The accumulative number is a string, and the numbers that make up it can form an accumulative sequence.

A valid cumulative sequence must contain at least three numbers. Except for the first two numbers, the other numbers in the string are equal to the sum of the previous two numbers.

Given a string containing only the number'0'-'9', write an algorithm to determine whether a given input is an accumulative number.

Explanation: Numbers in the cumulative sequence do not start with 0, so there will be no 1, 2, 03 or 1, 02, 3 cases.

  • Example 1:

Input: "112358"
Output: true
Interpretation: The cumulative sequence is: 1, 1, 2, 3, 5, 8. 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8

  • Example 2:

Input: "199100199"
Output: true
Interpretation: The cumulative sequence is: 1, 99, 100, 199. 1 + 99 = 100, 99 + 100 = 199

  • Advance:
    How do you handle an overflow of excessive integer input?

Source: LeetCode

# Reverse Solution Process
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"))

Explanation:

The test case "1203" on LeetCode results in False, which contradicts "12122 4036" as True.

  1. Reduce the range of nums by recursion.
  2. Simulate step to get possible summation.
  3. Cumulative combination of greed or violence; use known conditions to reduce unnecessary cycles.

Posted by bysable on Tue, 01 Oct 2019 21:52:12 -0700