HomeLeetcode306. Additive Number - Leetcode Solutions

306. Additive Number – Leetcode Solutions

Description

An additive number is a string whose digits can form an additive sequence.

A valid additive sequence should contain at least three numbers. Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.

Given a string containing only digits, return true if it is an additive number or false otherwise.

Note: Numbers in the additive sequence cannot have leading zeros, so sequence 1, 2, 03 or 1, 02, 3 is invalid.

Examples:

Example 1:

Input: "112358"
Output: true
Explanation: 
The digits can form an additive sequence: 1, 1, 2, 3, 5, 8. 
1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8

Example 2:

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

Solution in Python

Python
class Solution:
    def isAdditiveNumber(self, num: str) -> bool:
        # Helper function to check if a string can represent a valid number
        # It checks that the number doesn't have a leading zero unless it's '0'
        def isValidNumber(number: str) -> bool:
            return not (len(number) > 1 and number[0] == '0')

        # Main function that checks whether the string forms a valid additive sequence
        n = len(num)
        
        # Try every possible combination of the first two numbers
        for i in range(1, n):
            for j in range(i + 1, n):
                # First number is num[:i], second number is num[i:j]
                num1, num2 = num[:i], num[i:j]

                # Check if both numbers are valid (no leading zeros)
                if not isValidNumber(num1) or not isValidNumber(num2):
                    continue

                # Convert these numbers to integers
                x1, x2 = int(num1), int(num2)

                # Use the remaining part of the string to check if it forms an additive sequence
                k = j
                while k < n:
                    # Calculate the next number in the sequence
                    x3 = x1 + x2

                    # Convert this number to a string
                    x3_str = str(x3)

                    # Check if the next part of the string matches this number
                    if not num.startswith(x3_str, k):
                        break

                    # Move the pointers: shift x1, x2 to the next numbers
                    k += len(x3_str)
                    x1, x2 = x2, x3

                # If we have used the entire string and formed a valid sequence, return True
                if k == n:
                    return True

        # If no valid sequence was found, return False
        return False

Explanation:

  1. Helper function (isValidNumber): This checks whether a given number string is valid, ensuring no leading zeros (except for the number ‘0’).
  2. Main logic:
    • The outer loops try all combinations for the first two numbers in the sequence (num1 and num2).
    • It then checks if the remaining part of the string can form a valid additive sequence.
    • For each pair of num1 and num2, it iteratively computes the next number (x3 = x1 + x2), converts it to a string, and checks if the string matches the expected next part of the input num.
    • If the entire string is consumed and forms a valid sequence, the function returns True.
  3. Complexity considerations: The solution tries all possible pairs for the first two numbers and validates the sequence, which involves checking substrings. Given that num.length <= 35, this brute-force approach should run efficiently within the constraints.

Solution in C++

C++
class Solution {
public:
    // Helper function to check if two numbers can form a valid additive sequence
    bool isValid(string num, int start, int len1, int len2) {
        // If the first number has a leading zero and its length is greater than 1, it's invalid
        if (num[start] == '0' && len1 > 1) return false;
        // If the second number has a leading zero and its length is greater than 1, it's invalid
        if (num[start + len1] == '0' && len2 > 1) return false;
        
        // Convert the first and second parts of the string into numbers
        string num1 = num.substr(start, len1);
        string num2 = num.substr(start + len1, len2);
        
        // Start checking from the third part
        long long a = stoll(num1);
        long long b = stoll(num2);
        string sumStr;
        
        for (int i = start + len1 + len2; i < num.size(); i += sumStr.size()) {
            // Compute the sum of the previous two numbers
            long long sum = a + b;
            sumStr = to_string(sum);
            
            // If the remaining part of the string does not start with the computed sum, return false
            if (num.substr(i, sumStr.size()) != sumStr) return false;
            
            // Update a and b for the next iteration
            a = b;
            b = sum;
        }
        
        // If the loop completes without issues, it's a valid additive sequence
        return true;
    }

    bool isAdditiveNumber(string num) {
        int n = num.size();
        
        // We need at least 3 numbers for a valid sequence
        // Try different lengths for the first and second numbers
        for (int len1 = 1; len1 <= n / 2; ++len1) {
            for (int len2 = 1; max(len1, len2) <= n - len1 - len2; ++len2) {
                // Check if the numbers formed by the first len1 and len2 digits can create an additive sequence
                if (isValid(num, 0, len1, len2)) {
                    return true;
                }
            }
        }
        
        // If no valid sequence is found, return false
        return false;
    }
};

Solution in Javascript

JavaScript
function isValid(num, start, len1, len2) {
    // If the first number has a leading zero and it's longer than 1 digit, it's invalid
    if (num[start] === '0' && len1 > 1) return false;
    // If the second number has a leading zero and it's longer than 1 digit, it's invalid
    if (num[start + len1] === '0' && len2 > 1) return false;

    // Extract the first and second numbers from the string
    let num1 = num.substring(start, start + len1);
    let num2 = num.substring(start + len1, start + len1 + len2);

    // Convert them to integers
    let a = BigInt(num1);
    let b = BigInt(num2);
    
    // Iterate through the rest of the string to verify the sequence
    for (let i = start + len1 + len2; i < num.length;) {
        // Calculate the sum of the previous two numbers
        let sum = a + b;
        let sumStr = sum.toString();  // Convert the sum to a string

        // If the next part of the string doesn't match the calculated sum, return false
        if (!num.startsWith(sumStr, i)) return false;

        // Update a and b to the next two numbers in the sequence
        a = b;
        b = sum;

        // Move the index forward by the length of the sum
        i += sumStr.length;
    }

    // If we reach this point, it means the sequence is valid
    return true;
}


var isAdditiveNumber = function(num) {
    let n = num.length;

    // We need at least 3 numbers to form a valid additive sequence
    // Try different lengths for the first and second numbers
    for (let len1 = 1; len1 <= Math.floor(n / 2); len1++) {
        for (let len2 = 1; Math.max(len1, len2) <= n - len1 - len2; len2++) {
            // Check if the first two numbers (with lengths len1 and len2) can form a valid additive sequence
            if (isValid(num, 0, len1, len2)) {
                return true;  // If a valid sequence is found, return true
            }
        }
    }

    // If no valid sequence is found, return false
    return false;
};

Solution in Java

Java
class Solution {

    // Helper function to check if the sequence formed by the first two numbers is valid
    private boolean isValid(String num, int start, int len1, int len2) {
        // If the first number has a leading zero and its length is greater than 1, it's invalid
        if (num.charAt(start) == '0' && len1 > 1) return false;
        // If the second number has a leading zero and its length is greater than 1, it's invalid
        if (num.charAt(start + len1) == '0' && len2 > 1) return false;

        // Extract the first two numbers as substrings
        String num1 = num.substring(start, start + len1);
        String num2 = num.substring(start + len1, start + len1 + len2);

        // Convert the extracted numbers to long to avoid overflow
        long a = Long.parseLong(num1);
        long b = Long.parseLong(num2);
        
        // Start checking from the third number onward
        for (int i = start + len1 + len2; i < num.length();) {
            // Calculate the sum of the previous two numbers
            long sum = a + b;
            // Convert the sum to a string
            String sumStr = Long.toString(sum);
            
            // If the remaining part of the string doesn't start with the sum, return false
            if (!num.startsWith(sumStr, i)) return false;

            // Move the pointers forward for the next iteration
            a = b;
            b = sum;
            i += sumStr.length();
        }

        // If all numbers match the expected sums, return true
        return true;
    }

    public boolean isAdditiveNumber(String num) {
        int n = num.length();

        // Try different lengths for the first and second numbers
        // The maximum length for the first number is n / 2, and for the second number, it depends on the remaining digits
        for (int len1 = 1; len1 <= n / 2; len1++) {
            for (int len2 = 1; Math.max(len1, len2) <= n - len1 - len2; len2++) {
                // Check if a valid additive sequence can be formed with the first two numbers
                if (isValid(num, 0, len1, len2)) {
                    return true; // Return true if a valid sequence is found
                }
            }
        }

        // If no valid sequence is found, return false
        return false;
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular