String with additive sequence

Last Updated : 21 Oct, 2026

Given a string, the task is to find whether it contains an additive sequence or not. A string contains an additive sequence if its digits can make a sequence of numbers in which every number is addition of previous two numbers. A valid string should contain at least three digit to make one additive sequence.Ā 

Examples:Ā 

Input : s = ā€œ235813ā€
Output : true
Explanation: 2 + 3 = 5, 3 + 5 = 8, 5 + 8 = 13

Input : s = ā€œ199100199ā€
Output : true
Explanation: 1 + 99 = 100, 99 + 100 = 199

Input : s = ā€œ12345678ā€
Output : false

Try It Yourself
redirect icon

[Naive Approach] Recursion + String Addition – O(n³) Time and O(n) Space

The idea is to try all possible ways to split the string into the first two numbers, then check if the string after the two is sum of the two and recursively verify whether the rest of the string follows the additive sequence property.

  • Run two nested loops for i and j to try all possible combinations of first two strings of lengths i and j respectively.
  • Check if sum of substring from 0 to i-1 and i to i+j-1 is present at the index starting from i+j.
  • Recursively check if remaining string follows sum pattern
  • Return true if any valid sequence is found, otherwise false
C++
#include <bits/stdc++.h>
using namespace std;

// Checks whether num is valid or not, by
// checking first character and size
bool isValid(string num)
{
    // the length of the string cannot be less than 1.
    // If length > 1 and starts with 0, then invalid
    if (num.size() > 1 && num[0] == '0')
        return false;
    return true;
}

// returns int value at pos string, if pos is
// out of bound then returns 0
int val(string a, int pos)
{
    // since we are decrementing the pos,
    // we must check if it is less than 0
    if (pos < 0)
        return 0;

    // converting character to integer
    return (a[pos] - '0');
}

// add two number in string form and return
// result as a string
string addString(string a, string b)
{
    string sum = "";
    int i = a.length() - 1;
    int j = b.length() - 1;
    int carry = 0;

    // loop until both string get processed
    while (i >= 0 || j >= 0) {
        int t = val(a, i) + val(b, j) + carry;
        sum += (t % 10 + '0');
        carry = t / 10;
        i--;
        j--;
    }

    if (carry)
        sum += (carry + '0');

    reverse(sum.begin(), sum.end());
    return sum;
}

// Recursive method to check c = a + b
bool checkAddition(string a, string b, string c)
{
    // both first and second number should be valid
    if (!isValid(a) || !isValid(b))
        return false;

    string sum = addString(a, b);

    // if sum is same as c then direct return
    if (sum == c)
        return true;

    /* if sum size is greater than c, then no
       possible sequence further OR if c is not
       prefix of sum string, then no possible
       sequence further */
    if (c.size() <= sum.size()
        || sum != c.substr(0, sum.size()))
        return false;
    else {
        
        // next recursive call will have b as first
        // number, sum as second number and string
        // c as third number after removing prefix
        // sum string from c
        return checkAddition(b, sum,
                             c.substr(sum.size()));
    }
}

// Method returns true if string is additive
bool isSumString(string &s)
{
    int n = s.length();

    // loop until l/2 only, because if first
    // number is larger, then no possible sequence later
    for (int i = 1; i <= n / 2; i++) {
        for (int j = 1; j <= (n - i) / 2; j++) {

            if (checkAddition(s.substr(0, i),
                              s.substr(i, j),
                              s.substr(i + j))) {
                return true;
            }
        }
    }

    // If code execution reaches here, then string
    // doesn't have any additive sequence
    return false;
}

// Driver code
int main()
{
    string s = "235813";

    if (isSumString(s))
        cout << "true" << endl;
    else
        cout << "false" << endl;

    return 0;
}
Java
import java.util.*;

class GFG {

    // Checks whether num is valid or not, by
    // checking first character and size
    static boolean isValid(String num)
    {
        // the length of the string cannot be less than 1.
        // If length > 1 and starts with 0, then invalid
        if (num.length() > 1 && num.charAt(0) == '0')
            return false;
        return true;
    }

    // returns int value at pos string, if pos is
    // out of bound then returns 0
    static int val(String a, int pos)
    {
        // since we are decrementing the pos, we must check if it is less than 0
        if (pos < 0)
            return 0;

        // converting character to integer
        return (a.charAt(pos) - '0');
    }

    // add two number in string form and return
    // result as a string
    static String addString(String a, String b)
    {
        StringBuilder sum = new StringBuilder();
        int i = a.length() - 1;
        int j = b.length() - 1;
        int carry = 0;

        // loop until both string get processed
        while (i >= 0 || j >= 0) {
            int t = val(a, i) + val(b, j) + carry;
            sum.append((char)((t % 10) + '0'));
            carry = t / 10;
            i--;
            j--;
        }

        if (carry != 0)
            sum.append((char)(carry + '0'));

        return sum.reverse().toString();
    }

    // Recursive method to check c = a + b
    static boolean checkAddition(String a, String b, String c)
    {
        // both first and second number should be valid
        if (!isValid(a) || !isValid(b))
            return false;

        String sum = addString(a, b);

        // if sum is same as c then direct return
        if (sum.equals(c))
            return true;

        /* if sum size is greater than c, then no
           possible sequence further OR if c is not
           prefix of sum string, then no possible
           sequence further */
        if (c.length() <= sum.length()
                || !sum.equals(c.substring(0, sum.length())))
            return false;
        else {
            // next recursive call will have b as first
            // number, sum as second number and string
            // c as third number after removing prefix
            // sum string from c
            return checkAddition(b, sum,
                    c.substring(sum.length()));
        }
    }

    // Method returns true if string is additive
    static boolean isSumString(String s)
    {
        int l = s.length();

        // loop until l/2 only, because if first
        // number is larger, then no possible sequence later
        for (int i = 1; i <= l / 2; i++) {
            for (int j = 1; j <= (l - i) / 2; j++) {

                if (checkAddition(s.substring(0, i),
                        s.substring(i, i + j),
                        s.substring(i + j))) {
                    return true;
                }
            }
        }

        // If code execution reaches here, then string
        // doesn't have any additive sequence
        return false;
    }

    // Driver code
    public static void main(String[] args)
    {
        String s = "235813";

        if (isSumString(s))
            System.out.println("true");
        else
            System.out.println("false");
    }
}
Python
# Checks whether num is valid or not, by
# checking first character and size
def isValid(num):
    # the length of the string cannot be less than 1.
    # If length > 1 and starts with 0, then invalid
    if len(num) > 1 and num[0] == '0':
        return False
    return True


# returns int value at pos string, if pos is
# out of bound then returns 0
def val(a, pos):
    # since we are decrementing the pos, we must check if it is less than 0
    if pos < 0:
        return 0

    # converting character to integer
    return int(a[pos])


# add two number in string form and return
# result as a string
def addString(a, b):
    sum_str = ""
    i = len(a) - 1
    j = len(b) - 1
    carry = 0

    # loop until both string get processed
    while i >= 0 or j >= 0:
        t = val(a, i) + val(b, j) + carry
        sum_str += str(t % 10)
        carry = t // 10
        i -= 1
        j -= 1

    if carry:
        sum_str += str(carry)

    return sum_str[::-1]


# Recursive method to check c = a + b
def checkAddition(a, b, c):
    # both first and second number should be valid
    if not isValid(a) or not isValid(b):
        return False

    sum_str = addString(a, b)

    # if sum is same as c then direct return
    if sum_str == c:
        return True

    if len(c) <= len(sum_str) or sum_str != c[:len(sum_str)]:
        return False
    else:
        return checkAddition(b, sum_str, c[len(sum_str):])


# Method returns true if string is additive
def isSumString(s):
    l = len(s)

    for i in range(1, l // 2 + 1):
        for j in range(1, (l - i) // 2 + 1):

            if checkAddition(s[:i],
                             s[i:i + j],
                             s[i + j:]):
                return True

    return False


# Driver code
s = "235813"

if isSumString(s):
    print("true")
else:
    print("false")
C#
using System;

class GFG {

    // Checks whether num is valid or not, by
    // checking first character and size
    static bool isValid(string num)
    {
        if (num.Length > 1 && num[0] == '0')
            return false;
        return true;
    }

    // returns int value at pos string, if pos is
    // out of bound then returns 0
    static int val(string a, int pos)
    {
        if (pos < 0)
            return 0;

        return (a[pos] - '0');
    }

    // add two number in string form and return
    // result as a string
    static string addString(string a, string b)
    {
        string sum = "";
        int i = a.Length - 1;
        int j = b.Length - 1;
        int carry = 0;

        while (i >= 0 || j >= 0) {
            int t = val(a, i) + val(b, j) + carry;
            sum += (char)((t % 10) + '0');
            carry = t / 10;
            i--;
            j--;
        }

        if (carry != 0)
            sum += (char)(carry + '0');

        char[] arr = sum.ToCharArray();
        Array.Reverse(arr);
        return new string(arr);
    }

    // Recursive method to check c = a + b
    static bool checkAddition(string a, string b, string c)
    {
        if (!isValid(a) || !isValid(b))
            return false;

        string sum = addString(a, b);

        if (sum == c)
            return true;

        if (c.Length <= sum.Length ||
            sum != c.Substring(0, sum.Length))
            return false;
        else {
            return checkAddition(b, sum,
                c.Substring(sum.Length));
        }
    }

    // Method returns true if string is additive
    static bool isSumString(string s)
    {
        int l = s.Length;

        for (int i = 1; i <= l / 2; i++) {
            for (int j = 1; j <= (l - i) / 2; j++) {

                if (checkAddition(s.Substring(0, i),
                    s.Substring(i, j),
                    s.Substring(i + j))) {
                    return true;
                }
            }
        }

        return false;
    }

    // Driver code
    public static void Main()
    {
        string s = "235813";

        if (isSumString(s))
            Console.WriteLine("true");
        else
            Console.WriteLine("false");
    }
}
JavaScript
// Checks whether num is valid or not, by
// checking first character and size
function isValid(num)
{
    if (num.length > 1 && num[0] === '0')
        return false;
    return true;
}

// returns int value at pos string, if pos is
// out of bound then returns 0
function val(a, pos)
{
    if (pos < 0)
        return 0;

    return parseInt(a[pos]);
}

// add two number in string form and return
// result as a string
function addString(a, b)
{
    let sum = "";
    let i = a.length - 1;
    let j = b.length - 1;
    let carry = 0;

    while (i >= 0 || j >= 0) {
        let t = val(a, i) + val(b, j) + carry;
        sum += (t % 10).toString();
        carry = Math.floor(t / 10);
        i--;
        j--;
    }

    if (carry)
        sum += carry.toString();

    return sum.split("").reverse().join("");
}

// Recursive method to check c = a + b
function checkAddition(a, b, c)
{
    if (!isValid(a) || !isValid(b))
        return false;

    let sum = addString(a, b);

    if (sum === c)
        return true;

    if (c.length <= sum.length ||
        sum !== c.substring(0, sum.length))
        return false;
    else {
        return checkAddition(b, sum,
            c.substring(sum.length));
    }
}

// Method returns true if string is additive
function isSumString(s)
{
    let l = s.length;

    for (let i = 1; i <= Math.floor(l / 2); i++) {
        for (let j = 1; j <= Math.floor((l - i) / 2); j++) {

            if (checkAddition(s.substring(0, i),
                s.substring(i, i + j),
                s.substring(i + j))) {
                return true;
            }
        }
    }

    return false;
}

// Driver code
let s = "235813";

if (isSumString(s))
    console.log("true");
else
    console.log("false");

Output
true

[Better Approach] Iteration + String Simulation – O(n³) Time and O(n) Space

The idea is to simulate the additive sequence iteratively. We try all possible splits for the first two numbers and then keep generating the next number using string addition.

At each step, we check whether the generated sum matches the corresponding substring in the original string. If the sequence continues till the end, it is valid.

  • Try all possible splits for first and second numbers
  • Iteratively generate next numbers using string addition
  • Check if generated sum matches the next part of the string
  • Continue until string ends or mismatch occurs and return result
C++
#include <bits/stdc++.h>
using namespace std;

// Standard function to add two numbers given as strings (O(length))
string strAdd(const string &s1, const string &s2) {
    string sum;
    sum.reserve(max(s1.size(), s2.size()) + 1);
    int c = 0; // carry digit

    // Traverse both strings from right to left
    for (int i = (int)s1.size() - 1, j = (int)s2.size() - 1; i >= 0 || j >= 0; i--, j--) {
        int a = (i >= 0) ? (s1[i] - '0') : 0;
        int b = (j >= 0) ? (s2[j] - '0') : 0;

        int t = a + b + c;
        sum.push_back(t % 10 + '0');   // append at the back (O(1))
        c = t / 10;
    }

    if (c) sum.push_back(c + '0');

    reverse(sum.begin(), sum.end());   // reverse once at the end
    return sum;
}

// Checks whether the first two numbers f and s generate the rest of num
bool isAdditiveNumberUtil(const string &num, string f, string s) {

    int n = num.size();
    int i = f.size() + s.size();   // start index of the next number

    // At least one more number (the third) must exist
    if (i >= n) return false;

    while (i < n) {

        // Generate the next number
        string sum = strAdd(f, s);

        // The sum must match the string exactly at position i (no substr copy)
        if (num.compare(i, sum.size(), sum) != 0)
            return false;

        // Move forward in the sequence
        f = s;
        s = sum;
        i += sum.size();
    }

    // Valid only if the string was consumed exactly
    return i == n;
}

// Returns true if the string is an additive sequence
bool isSumString(string &s) {

    int len = s.size();

    if (len < 3) return false;

    // Try all possible splits for the first and second numbers
    for (int i = 0; i < len; i++) {

        // First number has a leading zero -> all longer first numbers are invalid too
        if (i > 0 && s[0] == '0') break;

        for (int j = i + 1; j < len; j++) {

            // Second number has a leading zero -> longer ones are invalid too
            if (j > i + 1 && s[i + 1] == '0') break;

            int len1 = i + 1;
            int len2 = j - i;

            // Third number is at least max(len1, len2) long; if not enough
            // characters remain, longer second numbers will not work either
            if (len - (j + 1) < max(len1, len2)) break;

            if (isAdditiveNumberUtil(s, s.substr(0, len1), s.substr(i + 1, len2)))
                return true;
        }
    }

    return false;
}

// Driver code 
int main() {
    string s = "235813";

    if (isSumString(s))
        cout << "true" << endl;
    else
        cout << "false" << endl;

    return 0;
}
Java
import java.util.*;

class GFG {

    // Standard function to add two numbers given as strings (O(length))
    static String strAdd(String s1, String s2) {
        StringBuilder sum = new StringBuilder();
        int c = 0; // carry digit

        // Traverse both strings from right to left
        for (int i = s1.length() - 1, j = s2.length() - 1; i >= 0 || j >= 0; i--, j--) {
            int a = i >= 0 ? (s1.charAt(i) - '0') : 0;
            int b = j >= 0 ? (s2.charAt(j) - '0') : 0;

            int t = a + b + c;
            sum.append((char) (t % 10 + '0'));   // append at the back (O(1))
            c = t / 10;
        }

        if (c != 0) sum.append((char) (c + '0'));

        return sum.reverse().toString();         // reverse once at the end
    }

    // Checks whether the first two numbers f and s generate the rest of num
    static boolean isAdditiveNumberUtil(String num, String f, String s) {

        int n = num.length();
        int i = f.length() + s.length();   // start index of the next number

        // At least one more number (the third) must exist
        if (i >= n) return false;

        while (i < n) {

            // Generate the next number
            String sum = strAdd(f, s);

            // The sum must match the string exactly at position i (no substring copy)
            if (!num.startsWith(sum, i))
                return false;

            // Move forward in the sequence
            f = s;
            s = sum;
            i += sum.length();
        }

        // Valid only if the string was consumed exactly
        return i == n;
    }

    // Returns true if the string is an additive sequence
    static boolean isSumString(String s) {

        int len = s.length();

        if (len < 3) return false;

        // Try all possible splits for the first and second numbers
        for (int i = 0; i < len; i++) {

            // First number has a leading zero -> longer first numbers are invalid too
            if (i > 0 && s.charAt(0) == '0') break;

            for (int j = i + 1; j < len; j++) {

                // Second number has a leading zero -> longer ones are invalid too
                if (j > i + 1 && s.charAt(i + 1) == '0') break;

                int len1 = i + 1;
                int len2 = j - i;

                // Third number is at least max(len1, len2) long; if not enough
                // characters remain, longer second numbers will not work either
                if (len - (j + 1) < Math.max(len1, len2)) break;

                if (isAdditiveNumberUtil(s, s.substring(0, len1), s.substring(i + 1, j + 1)))
                    return true;
            }
        }

        return false;
    }

    // Driver code 
    public static void main(String[] args) {
        String s = "235813";

        if (isSumString(s))
            System.out.println("true");
        else
            System.out.println("false");
    }
}
Python
# Standard function to add two numbers given as strings
def strAdd(s1, s2):
    res = []
    c = 0  # carry digit
    i = len(s1) - 1
    j = len(s2) - 1

    # Traverse both strings from right to left
    while i >= 0 or j >= 0:
        a = ord(s1[i]) - 48 if i >= 0 else 0
        b = ord(s2[j]) - 48 if j >= 0 else 0

        t = a + b + c
        res.append(chr(t % 10 + 48))   # append at the back (O(1))
        c = t // 10

        i -= 1
        j -= 1

    if c:
        res.append(str(c))

    return "".join(reversed(res))      # reverse once at the end


# Checks whether the first two numbers f and s generate the rest of num
def isAdditiveNumberUtil(num, f, s):
    n = len(num)
    i = len(f) + len(s)    # start index of the next number

    # At least one more number (the third) must exist
    if i >= n:
        return False

    while i < n:
        # Generate the next number
        sum_str = strAdd(f, s)

        # The sum must match the string exactly at position i (no slicing copy)
        if not num.startswith(sum_str, i):
            return False

        # Move forward in the sequence
        f = s
        s = sum_str
        i += len(sum_str)

    # Valid only if the string was consumed exactly
    return i == n


# Returns True if the string is an additive sequence
def isSumString(s):
    length = len(s)

    if length < 3:
        return False

    # Try all possible splits for the first and second numbers
    for i in range(length):

        # First number has a leading zero -> longer first numbers are invalid too
        if i > 0 and s[0] == '0':
            break

        for j in range(i + 1, length):

            # Second number has a leading zero -> longer ones are invalid too
            if j > i + 1 and s[i + 1] == '0':
                break

            len1 = i + 1
            len2 = j - i

            # Third number is at least max(len1, len2) long; if not enough
            # characters remain, longer second numbers will not work either
            if length - (j + 1) < max(len1, len2):
                break

            if isAdditiveNumberUtil(s, s[:len1], s[i + 1:j + 1]):
                return True

    return False


# Driver code 
s = "235813"

if isSumString(s):
    print("true")
else:
    print("false")
C#
using System;
using System.Text;

class GFG {

    // Standard function to add two numbers given as strings (O(length))
    static string strAdd(string s1, string s2) {
        StringBuilder sum = new StringBuilder();
        int c = 0; // carry digit

        // Traverse both strings from right to left
        for (int i = s1.Length - 1, j = s2.Length - 1; i >= 0 || j >= 0; i--, j--) {
            int a = i >= 0 ? (s1[i] - '0') : 0;
            int b = j >= 0 ? (s2[j] - '0') : 0;

            int t = a + b + c;
            sum.Append((char)(t % 10 + '0'));   // append at the back (O(1))
            c = t / 10;
        }

        if (c != 0) sum.Append((char)(c + '0'));

        // Reverse once at the end
        char[] arr = sum.ToString().ToCharArray();
        Array.Reverse(arr);
        return new string(arr);
    }

    // Checks whether num has the substring 'sum' exactly at position pos (no copy)
    static bool matchAt(string num, int pos, string sum) {
        if (pos + sum.Length > num.Length) return false;
        return string.CompareOrdinal(num, pos, sum, 0, sum.Length) == 0;
    }

    // Checks whether the first two numbers f and s generate the rest of num
    static bool isAdditiveNumberUtil(string num, string f, string s) {

        int n = num.Length;
        int i = f.Length + s.Length;   // start index of the next number

        // At least one more number (the third) must exist
        if (i >= n) return false;

        while (i < n) {

            // Generate the next number
            string sum = strAdd(f, s);

            // The sum must match the string exactly at position i
            if (!matchAt(num, i, sum))
                return false;

            // Move forward in the sequence
            f = s;
            s = sum;
            i += sum.Length;
        }

        // Valid only if the string was consumed exactly
        return i == n;
    }

    // Returns true if the string is an additive sequence
    static bool isSumString(string s) {

        int len = s.Length;

        if (len < 3) return false;

        // Try all possible splits for the first and second numbers
        for (int i = 0; i < len; i++) {

            // First number has a leading zero -> longer first numbers are invalid too
            if (i > 0 && s[0] == '0') break;

            for (int j = i + 1; j < len; j++) {

                // Second number has a leading zero -> longer ones are invalid too
                if (j > i + 1 && s[i + 1] == '0') break;

                int len1 = i + 1;
                int len2 = j - i;

                // Third number is at least max(len1, len2) long; if not enough
                // characters remain, longer second numbers will not work either
                if (len - (j + 1) < Math.Max(len1, len2)) break;

                if (isAdditiveNumberUtil(s, s.Substring(0, len1), s.Substring(i + 1, len2)))
                    return true;
            }
        }

        return false;
    }

    // Driver code 
    public static void Main() {
        string s = "235813";

        if (isSumString(s))
            Console.WriteLine("true");
        else
            Console.WriteLine("false");
    }
}
JavaScript
// Standard function to add two numbers given as strings (O(length))
function strAdd(s1, s2) {
    let res = [];
    let c = 0; // carry digit

    // Traverse both strings from right to left
    for (let i = s1.length - 1, j = s2.length - 1; i >= 0 || j >= 0; i--, j--) {
        let a = i >= 0 ? (s1.charCodeAt(i) - 48) : 0;
        let b = j >= 0 ? (s2.charCodeAt(j) - 48) : 0;

        let t = a + b + c;
        res.push(t % 10);              // append at the back (O(1))
        c = t >= 10 ? 1 : 0;
    }

    if (c) res.push(c);

    return res.reverse().join("");     // reverse once at the end
}

// Checks whether num has the string 'sum' exactly at position pos (no substring copy)
function matchAt(num, pos, sum) {
    if (pos + sum.length > num.length) return false;
    for (let k = 0; k < sum.length; k++) {
        if (num.charCodeAt(pos + k) !== sum.charCodeAt(k)) return false;
    }
    return true;
}

// Checks whether the first two numbers f and s generate the rest of num
function isAdditiveNumberUtil(num, f, s) {

    let n = num.length;
    let i = f.length + s.length;   // start index of the next number

    // At least one more number (the third) must exist
    if (i >= n) return false;

    while (i < n) {

        // Generate the next number
        let sum = strAdd(f, s);

        // The sum must match the string exactly at position i
        if (!matchAt(num, i, sum))
            return false;

        // Move forward in the sequence
        f = s;
        s = sum;
        i += sum.length;
    }

    // Valid only if the string was consumed exactly
    return i === n;
}

// Returns true if the string is an additive sequence
function isSumString(s) {

    let len = s.length;

    if (len < 3) return false;

    // Try all possible splits for the first and second numbers
    for (let i = 0; i < len; i++) {

        // First number has a leading zero -> longer first numbers are invalid too
        if (i > 0 && s[0] === '0') break;

        for (let j = i + 1; j < len; j++) {

            // Second number has a leading zero -> longer ones are invalid too
            if (j > i + 1 && s[i + 1] === '0') break;

            let len1 = i + 1;
            let len2 = j - i;

            // Third number is at least max(len1, len2) long; if not enough
            // characters remain, longer second numbers will not work either
            if (len - (j + 1) < Math.max(len1, len2)) break;

            if (isAdditiveNumberUtil(s, s.substring(0, len1), s.substring(i + 1, j + 1)))
                return true;
        }
    }

    return false;
}

// Driver code 
let s = "235813";

if (isSumString(s))
    console.log("true");
else
    console.log("false");

Output
true
Comment