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 = 13Input : s = “199100199”
Output : true
Explanation: 1 + 99 = 100, 99 + 100 = 199Input : s = “12345678”
Output : false
Table of Content
[Naive Approach] Using 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
#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 isAdditive(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 (isAdditive(s))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}
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 isAdditive(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 <= n / 2; i++) {
for (int j = 1; j <= (n - 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 (isAdditive(s))
System.out.println("true");
else
System.out.println("false");
}
}
# 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 isAdditive(s):
l = len(s)
for i in range(1, n // 2 + 1):
for j in range(1, (n - i) // 2 + 1):
if checkAddition(s[:i],
s[i:i + j],
s[i + j:]):
return True
return False
# Driver code
s = "235813"
if isAdditive(s):
print("true")
else:
print("false")
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 isAdditive(string s)
{
int l = s.Length;
for (int i = 1; i <= n / 2; i++) {
for (int j = 1; j <= (n - 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 (isAdditive(s))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
// 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 isAdditive(s)
{
let l = s.length;
for (let i = 1; i <= Math.floor(n / 2); i++) {
for (let j = 1; j <= Math.floor((n - 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 (isAdditive(s))
console.log("true");
else
console.log("false");
Output
true
[Better Approach] Using Iteration + String Simulation – O(n³) Time and O(n) Space
The idea is to avoid deep recursion and instead 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
#include <bits/stdc++.h>
using namespace std;
// standard function to add two string
string strAdd(string s1, string s2){
string sum;
int c = 0; // carry digit
// traversing both strings from right to left
for(int i = s1.size()-1, j = s2.size()-1; i >= 0 || j >= 0; i--, j--){
// take digit from s1 if exists, else 0
int a = i >= 0 ? (s1[i] - '0') : 0;
// take digit from s2 if exists, else 0
int b = j >= 0 ? (s2[j] - '0') : 0;
// sum current digits with carry and store last digit
sum = to_string((a + b + c) % 10) + sum;
// update carry for next iteration
c = (a + b + c) / 10;
}
// if carry remains, add it at front
return c ? "1" + sum : sum;
}
// utility function which checks whether the current two strings
// follow additive sequence for remaining string
bool isAdditiveNumberUtil(string &num, string f, string s){
// starting index for next number after f and s
int i = f.size() + s.size();
// loop until we reach end of string
while(i < num.size()){
// if any number has leading zero and length > 1, invalid
if((f.size() > 1 && f[0] == '0') || (s.size() > 1 && s[0] == '0'))
break;
// find sum of previous two numbers
string sum = strAdd(f, s);
// if sum matches remaining string exactly, valid sequence
if(sum == num.substr(i, num.size() - i))
return true;
// move forward in sequence
f = s;
s = sum;
i += sum.size();
}
// no valid sequence found
return false;
}
// Method returns true if string is additive
bool isAdditive(string &s) {
// size of the string
int len = s.size();
// if size is less than 3, not possible
if(len < 3) return false;
// try all possible splits for first and second number
for(int i = 0; i < len; i++)
for(int j = i + 1; j < len; j++)
// check if this split forms valid additive sequence
if(isAdditiveNumberUtil(s,
s.substr(0, i+1),
s.substr(i+1, j-i)))
return true;
// no valid additive sequence found
return false;
}
// Driver code
int main()
{
string s = "235813";
if (isAdditive(s))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}
import java.util.*;
class GFG {
// standard function to add two string
static String strAdd(String s1, String s2){
String sum = "";
int c = 0; // carry digit
// traversing both strings from right to left
for(int i = s1.length()-1, j = s2.length()-1; i >= 0 || j >= 0; i--, j--){
// take digit from s1 if exists, else 0
int a = i >= 0 ? (s1.charAt(i) - '0') : 0;
// take digit from s2 if exists, else 0
int b = j >= 0 ? (s2.charAt(j) - '0') : 0;
// sum current digits with carry and store last digit
sum = ((a + b + c) % 10) + sum;
// update carry for next iteration
c = (a + b + c) / 10;
}
// if carry remains, add it at front
return c != 0 ? "1" + sum : sum;
}
// utility function which checks whether the current two strings
// follow additive sequence for remaining string
static boolean isAdditiveNumberUtil(String num, String f, String s){
// starting index for next number after f and s
int i = f.length() + s.length();
// loop until we reach end of string
while(i < num.length()){
// if any number has leading zero and length > 1, invalid
if((f.length() > 1 && f.charAt(0) == '0') || (s.length() > 1 && s.charAt(0) == '0'))
break;
// find sum of previous two numbers
String sum = strAdd(f, s);
// if sum matches remaining string exactly → valid sequence
if(sum.equals(num.substring(i)))
return true;
// move forward in sequence
f = s;
s = sum;
i += sum.length();
}
// no valid sequence found
return false;
}
// Method returns true if string is additive
static boolean isAdditive(String s) {
// size of the string
int len = s.length();
// if size is less than 3, not possible
if(len < 3) return false;
// try all possible splits for first and second number
for(int i = 0; i < len; i++)
for(int j = i + 1; j < len; j++)
// check if this split forms valid additive sequence
if(isAdditiveNumberUtil(s,
s.substring(0, i+1),
s.substring(i+1, j+1)))
return true;
// no valid additive sequence found
return false;
}
// Driver code
public static void main(String[] args)
{
String s = "235813";
if (isAdditive(s))
System.out.println("true");
else
System.out.println("false");
}
}
# standard function to add two string
def strAdd(s1, s2):
sum_str = ""
c = 0 # carry digit
# traversing both strings from right to left
i = len(s1) - 1
j = len(s2) - 1
while i >= 0 or j >= 0:
# take digit from s1 if exists, else 0
a = int(s1[i]) if i >= 0 else 0
# take digit from s2 if exists, else 0
b = int(s2[j]) if j >= 0 else 0
# sum current digits with carry and store last digit
sum_str = str((a + b + c) % 10) + sum_str
# update carry for next iteration
c = (a + b + c) // 10
i -= 1
j -= 1
# if carry remains, add it at front
return ("1" + sum_str) if c else sum_str
# utility function which checks whether the current two strings
# follow additive sequence for remaining string
def isAdditiveNumberUtil(num, f, s):
# starting index for next number after f and s
i = len(f) + len(s)
# loop until we reach end of string
while i < len(num):
# if any number has leading zero and length > 1, invalid
if (len(f) > 1 and f[0] == '0') or (len(s) > 1 and s[0] == '0'):
break
# find sum of previous two numbers
sum_str = strAdd(f, s)
# if sum matches remaining string exactly → valid sequence
if sum_str == num[i:]:
return True
# move forward in sequence
f = s
s = sum_str
i += len(sum_str)
# no valid sequence found
return False
# Method returns true if string is additive
def isAdditive(s):
# size of the string
length = len(s)
# if size is less than 3, not possible
if length < 3:
return False
# try all possible splits for first and second number
for i in range(length):
for j in range(i + 1, length):
# check if this split forms valid additive sequence
if isAdditiveNumberUtil(s,
s[:i+1],
s[i+1:j+1]):
return True
# no valid additive sequence found
return False
# Driver code
s = "235813"
if isAdditive(s):
print("true")
else:
print("false")
using System;
class GFG {
// standard function to add two string
static string strAdd(string s1, string s2){
string sum = "";
int c = 0; // carry digit
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;
sum = ((a + b + c) % 10) + sum;
c = (a + b + c) / 10;
}
return c != 0 ? "1" + sum : sum;
}
// utility function which checks whether the current two strings
// follow additive sequence for remaining string
static bool isAdditiveNumberUtil(string num, string f, string s){
int i = f.Length + s.Length;
while(i < num.Length){
if((f.Length > 1 && f[0] == '0') || (s.Length > 1 && s[0] == '0'))
break;
string sum = strAdd(f, s);
if(sum == num.Substring(i))
return true;
f = s;
s = sum;
i += sum.Length;
}
return false;
}
// Method returns true if string is additive
static bool isAdditive(string s) {
int len = s.Length;
if(len < 3) return false;
for(int i = 0; i < len; i++)
for(int j = i + 1; j < len; j++)
if(isAdditiveNumberUtil(s,
s.Substring(0, i+1),
s.Substring(i+1, j-i)))
return true;
return false;
}
// Driver code
public static void Main()
{
string s = "235813";
if (isAdditive(s))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
// standard function to add two string
function strAdd(s1, s2){
let sum = "";
let c = 0; // carry digit
for(let i = s1.length-1, j = s2.length-1; i >= 0 || j >= 0; i--, j--){
let a = i >= 0 ? (s1[i] - '0') : 0;
let b = j >= 0 ? (s2[j] - '0') : 0;
sum = ((a + b + c) % 10) + sum;
c = Math.floor((a + b + c) / 10);
}
return c ? "1" + sum : sum;
}
// utility function which checks whether the current two strings
// follow additive sequence for remaining string
function isAdditiveNumberUtil(num, f, s){
let i = f.length + s.length;
while(i < num.length){
if((f.length > 1 && f[0] === '0') || (s.length > 1 && s[0] === '0'))
break;
let sum = strAdd(f, s);
if(sum === num.substring(i))
return true;
f = s;
s = sum;
i += sum.length;
}
return false;
}
// Method returns true if string is additive
function isAdditive(s) {
let len = s.length;
if(len < 3) return false;
for(let i = 0; i < len; i++)
for(let j = i + 1; j < len; j++)
if(isAdditiveNumberUtil(s,
s.substring(0, i+1),
s.substring(i+1, j+1)))
return true;
return false;
}
// Driver code
let s = "235813";
if (isAdditive(s))
console.log("true");
else
console.log("false");
Output
true