带有加法序列的字符串 |第 2 组
给定一个字符串str ,任务是找出它是否包含一个加法序列。一个字符串包含一个加法序列,如果它的数字可以组成一个数字序列,其中每个数字都是前两个数字的加法。一个有效的字符串应该至少包含三个数字来构成一个加法序列。
例子:
Input: str = “235813”
Output: true
Explanation : One of the possible sequence is: 2 , 3 , 5 , 8 , 13
where 3 = 1 + 2 , 5 = 3 + 2 , 8 = 5 + 3 and 13 = 8 + 5 .
Input: str = “199100199”
Output: true
Explanation : One of the possible sequence is : 1 , 99 , 100 , 199
where 100 = 99 + 1 , 199 = 100 + 99 gives the additive sequence.
Input: str = “12345678”
Output: false
Explanation: No such sequence possible
方法:本文的Set-1中讨论了递归方法。
回溯方法:上述问题可以通过以下方式使用回溯来解决。
- 根据问题陈述的基本要求之一是检查给定字符串是否遵循加法序列的属性,即序列中的每个数字都是前两个数字的和,并且该属性对于序列中的所有数字都成立。
- 因此,对于如何选择序列中的前两个数字没有限制(因为需要两个数字来检查加法序列属性)。
- 所以尝试所有可能的方法来生成系列中的前两个数字,然后从第三个数字开始进行比较,即为了保持加法序列属性,系列中的下一个数字必须是前两个数字的总和。
- 因此,如果在任何时间点到目前为止生成的数字超过了前两个数字的总和,则不再需要继续进行,因为这个数字永远不会成为加法序列的一部分。在这种情况下,回溯并尝试其余的组合。
- 如果到目前为止生成的数字是前两个数字的总和,则使用前两个数字作为参考对剩余的字符串进行递归,如果到达字符串的末尾并且加法序列的长度(向量的大小)为大于或等于 3 则给定的字符串有一个加法序列。
- 找到加法序列的时刻将全局布尔变量标记为真(表示我们已经找到了解决方案并避免检查其余组合)。
下面是上面的实现。
C++
// C++ code to implement the approach
#include
using namespace std;
// Variable to store the result
bool res;
// Function to check the additive sequence
void check_additive(string s,
vector& v,
long st)
{
// If the end is reached and vector
// consists of more than 2 numbers then
// one of the possible solution is found
if (st == s.length() and v.size() > 2) {
// Mark the res as true to indicate
// the solution is found and
// to avoid for trying
// the rest of the combinations
res = true;
return;
}
long long a, b, c = 0;
if (v.size() >= 2) {
// Store the previous two numbers
// of the sequence to check the
// additive sequence property
// for the next number
b = v[v.size() - 1];
a = v[v.size() - 2];
}
for (long i = st; i < s.length(); i++) {
// Generate the number
c = c * 10 + (s[i] - '0');
// Try all the possible ways
// to generate the first two numbers
// i.e. if vector consists of
// less than two numbers and
// no solution is found yet
if (v.size() < 2 and !res) {
v.push_back(c);
check_additive(s, v, i + 1);
// Pop the value to try for the
// other combination
v.pop_back();
}
// If the number generated so far
// is greater than the sum of
// previous two numbers in
// the sequence then it cannot be
// a part of additive sequence
// hence no need to proceed further
else if (c > (a + b) and !res)
return;
// If the number generated so far
// is equal to the sum of
// previous two numbers then
// it can be a part of additive
// sequence; push it into vector
// and check for remaining string
else if (c == a + b and !res) {
// Store it in the vector
v.push_back(c);
// Recur for remaining string
check_additive(s, v, i + 1);
// If unable to find solution
// pop it and try for
// other combination
v.pop_back();
}
}
return;
}
// Function to check if additive sequence
bool isAdditiveSequence(string str)
{
// In order to form additive sequence
// the length of the string
// must be atleast three
if (str.length() <= 2)
return false;
vector v;
res = false;
check_additive(str, v, 0);
return res;
}
// Driver code
int main()
{
string str = "199100199";
bool ans = isAdditiveSequence(str);
if (ans)
cout << "true";
else
cout << "false";
return 0;
}
Java
// Java code to implement the approach
import java.util.ArrayList;
class GFG {
// Variable to store the result
static boolean res;
// Function to check the additive sequence
static void check_additive(String s,
ArrayList v,
int st)
{
// If the end is reached and vector
// consists of more than 2 numbers then
// one of the possible solution is found
if (st == s.length() && v.size() > 2) {
// Mark the res as true to indicate
// the solution is found and
// to avoid for trying
// the rest of the combinations
res = true;
return;
}
int a = 0, b = 0, c = 0;
if (v.size() >= 2) {
// Store the previous two numbers
// of the sequence to check the
// additive sequence property
// for the next number
b = v.get(v.size() - 1);
a = v.get(v.size() - 2);
}
for (int i = st; i < s.length(); i++) {
// Generate the number
c = c * 10 + (s.charAt(i) - '0');
// Try all the possible ways
// to generate the first two numbers
// i.e. if vector consists of
// less than two numbers and
// no solution is found yet
if (v.size() < 2 && !res) {
v.add(c);
check_additive(s, v, i + 1);
// Pop the value to try for the
// other combination
v.remove(v.size() - 1);
}
// If the number generated so far
// is greater than the sum of
// previous two numbers in
// the sequence then it cannot be
// a part of additive sequence
// hence no need to proceed further
else if (c > (a + b) && !res)
return;
// If the number generated so far
// is equal to the sum of
// previous two numbers then
// it can be a part of additive
// sequence; push it into vector
// and check for remaining String
else if (c == a + b && !res) {
// Store it in the vector
v.add(c);
// Recur for remaining String
check_additive(s, v, i + 1);
// If unable to find solution
// pop it and try for
// other combination
v.remove(v.size() - 1);
}
}
return;
}
// Function to check if additive sequence
static boolean isAdditiveSequence(String str)
{
// In order to form additive sequence
// the length of the String
// must be atleast three
if (str.length() <= 2)
return false;
ArrayList v = new ArrayList();
res = false;
check_additive(str, v, 0);
return res;
}
// Driver code
public static void main(String args[]) {
String str = "199100199";
boolean ans = isAdditiveSequence(str);
if (ans)
System.out.println("true");
else
System.out.println("false");
}
}
// This code is contributed by saurabh_jaiswal.
Python3
# python3 code to implement the approach
# Variable to store the result
res = 0
v = []
# Function to check the additive sequence
def check_additive(s, st):
global res
global v
# If the end is reached and vector
# consists of more than 2 numbers then
# one of the possible solution is found
if (st == len(s) and len(v) > 2):
# Mark the res as true to indicate
# the solution is found and
# to avoid for trying
# the rest of the combinations
res = True
return
a, b, c = 0, 0, 0
if (len(v) >= 2):
# Store the previous two numbers
# of the sequence to check the
# additive sequence property
# for the next number
b = v[len(v) - 1]
a = v[len(v) - 2]
for i in range(st, len(s)):
# Generate the number
c = c * 10 + (ord(s[i]) - ord('0'))
# Try all the possible ways
# to generate the first two numbers
# i.e. if vector consists of
# less than two numbers and
# no solution is found yet
if (len(v) < 2 and (not res)):
v.append(c)
check_additive(s, i + 1)
# Pop the value to try for the
# other combination
v.pop()
# If the number generated so far
# is greater than the sum of
# previous two numbers in
# the sequence then it cannot be
# a part of additive sequence
# hence no need to proceed further
elif (c > (a + b) and not res):
return
# If the number generated so far
# is equal to the sum of
# previous two numbers then
# it can be a part of additive
# sequence; push it into vector
# and check for remaining string
elif (c == a + b and not res):
# Store it in the vector
v.append(c)
# Recur for remaining string
check_additive(s, i + 1)
# If unable to find solution
# pop it and try for
# other combination
v.pop()
return
# Function to check if additive sequence
def isAdditiveSequence(str):
global res
# In order to form additive sequence
# the length of the string
# must be atleast three
if (len(str) <= 2):
return False
res = False
check_additive(str, 0)
return res
# Driver code
if __name__ == "__main__":
str = "199100199"
ans = isAdditiveSequence(str)
if (ans):
print("true")
else:
print("false")
# This code is contributed by rakeshsahni
C#
// C# program of the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Variable to store the result
static bool res;
// Function to check the Additive sequence
static void check_Additive(string s,
List v,
int st)
{
// If the end is reached and vector
// consists of more than 2 numbers then
// one of the possible solution is found
if (st == s.Length && v.Count > 2) {
// Mark the res as true to indicate
// the solution is found and
// to avoid for trying
// the rest of the combinations
res = true;
return;
}
int a = 0, b = 0, c = 0;
if (v.Count >= 2) {
// Store the previous two numbers
// of the sequence to check the
// Additive sequence property
// for the next number
b = v[v.Count - 1];
a = v[v.Count - 2];
}
for (int i = st; i < s.Length; i++) {
// Generate the number
c = c * 10 + (s[i] - '0');
// Try all the possible ways
// to generate the first two numbers
// i.e. if vector consists of
// less than two numbers and
// no solution is found yet
if (v.Count < 2 && !res) {
v.Add(c);
check_Additive(s, v, i + 1);
// Pop the value to try for the
// other combination
v.Remove(v.Count - 1);
}
// If the number generated so far
// is greater than the sum of
// previous two numbers in
// the sequence then it cannot be
// a part of Additive sequence
// hence no need to proceed further
else if (c > (a + b) && !res)
return;
// If the number generated so far
// is equal to the sum of
// previous two numbers then
// it can be a part of Additive
// sequence; push it into vector
// and check for remaining String
else if (c == a + b && !res) {
// Store it in the vector
v.Add(c);
// Recur for remaining String
check_Additive(s, v, i + 1);
// If unable to find solution
// pop it and try for
// other combination
v.Remove(v.Count - 1);
}
}
return;
}
// Function to check if Additive sequence
static bool isAdditiveSequence(string str)
{
// In order to form Additive sequence
// the length of the String
// must be atleast three
if (str.Length <= 2)
return false;
List v = new List();
res = true;
check_Additive(str, v, 0);
return res;
}
// Driver Code
public static void Main()
{
string str = "199100199";
bool ans = isAdditiveSequence(str);
if (ans)
Console.Write("true");
else
Console.Write("false");
}
}
// This code is contributed by sanjoy_62.
Javascript
输出
true
时间复杂度: O(N*N)
辅助空间: O(N)