Open In App

Partition given string in such manner that i’th substring is sum of (i-1)’th and (i-2)’th substring

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Partition given string in such manner that i’th substring is sum of (i-1)’th and (i-2)’nd substring. 

Examples:

Input : "11235813"
Output : ["1", "1", "2", "3", "5", "8", "13"]

Input : "1111223"
Output : ["1", "11", "12", "23"]

Input : "1111213"
Output : ["11", "1", "12", "13"]

Input : "11121114"
Output : []
  1. Iterate through the given string by picking 3 numbers (first, seconds and third) at a time starting from one digit each. 
  2. If first + second = third, recursively call check() with second as first and third as second. The third is picked based on next possible number of digits. (The result of addition of two numbers can have a max. of second’s & third’s digits + 1) 
  3. Else, first increment the third (by adding more digits) till the limit (Here limit is sum of first and second). 
  4. After incrementing third, following cases arise. a) When doesn’t match, increment the second offset. b) When doesn’t match, increment the first offset. c) 
    • Note: Once a call to check() is made after incrementing the third offset, do not alter the second or first, as those are already finalized. 
  5. When the end of the string is reached and the condition is satisfied, add “second” and “third” to the empty list. While rolling back the recursive stack, prepend the “first” to the list so the order is preserved. 

Implementation:

Java




// Java program to check if we can partition a
// string in a way that value of i-th string is
// sum of (i-1)-th and (i-2)-th substrings.
import java.util.LinkedList;
 
public class SumArray {
 
private static LinkedList<Integer> resultList =
        new LinkedList<>();
 
private static boolean check(char[] chars, int offset1,
 int offset2, int offset3, boolean freezeFirstAndSecond) {
 
 // Find subarrays according to given offsets
 int first = intOf(subArr(chars, 0, offset1));
 int second = intOf(subArr(chars, offset1, offset2));
 int third = intOf(subArr(chars, offset1 + offset2, offset3));
 
 // If condition is satisfied for current subarrays
 if (first + second == third) {
 
 // If whole array is covered.
 if (offset1 + offset2 + offset3 >= chars.length) {
  resultList.add(first);
  resultList.add(second);
  resultList.add(third);
  return true;
 }
   
 // Check if remaining array also satisfies the condition
 boolean result = check(subArr(chars, offset1,
  chars.length - offset1), offset2, offset3,
    Math.max(offset2, offset3), true);
 if (result) {
  resultList.addFirst(first);
 }
 return result;
 }
 
 // If not satisfied, try incrementing third
 if (isValidOffSet(offset1, offset2, 1 + offset3, chars.length)) {
 if (check(chars, offset1, offset2, 1 + offset3, false))
  return true
 }
 
 // If first and second have been finalized, do not
 // alter already computed results
 if (freezeFirstAndSecond)
 return false;
 
 // If first and second are not finalized
 if (isValidOffSet(offset1, 1 + offset2, Math.max(offset1,
      1 + offset2), chars.length)) {
 
 // Try incrementing second
 if (check(chars, offset1, 1 + offset2,
  Math.max(offset1, 1 + offset2), false))
  return true
 }
 
 // Try incrementing first
 if (isValidOffSet(1 + offset1, offset2, Math.max(1 + offset1,
        offset2), chars.length)) {
 if (check(chars, 1 + offset1, offset2, Math.max(1 + offset1,
           offset2), false))
  return true;
 }
 return false;
}
 
// Check if given three offsets are valid (Within array length
// and third offset can represent sum of first two)
private static boolean isValidOffSet(int offset1, int offset2,
        int offset3, int length) {
 return (offset1 + offset2 + offset3 <= length &&
   (offset3 == Math.max(offset1, offset2) ||
   offset3 == 1 + Math.max(offset1, offset2)));
}
 
// To get a subarray with starting from given
// index and offset
private static char[] subArr(char[] chars, int index, int offset) {
 int trueOffset = Math.min(chars.length - index, offset);
 char[] destArr = new char[trueOffset];
 System.arraycopy(chars, index, destArr, 0, trueOffset);
 return destArr;
}
 
private static int intOf(char... chars) {
 return Integer.valueOf(new String(chars));
}
 
public static void main(String[] args) {
 String numStr = "11235813";
 char[] chars = numStr.toCharArray();
 System.out.println(check(chars, 1, 1, 1, false));
 System.out.println(resultList);
}
}


C++




#include <iostream>
#include <list>
#include <algorithm>
 
using namespace std;
 
list<int> resultList;
 
bool check(string chars, int offset1, int offset2, int offset3, bool freezeFirstAndSecond) {
 
    // Find substrings according to given offsets
    string first = chars.substr(0, offset1);
    string second = chars.substr(offset1, offset2);
    string third = chars.substr(offset1 + offset2, offset3);
 
    // If condition is satisfied for current substrings
    if (stoi(first) + stoi(second) == stoi(third)) {
 
        // If whole string is covered.
        if (offset1 + offset2 + offset3 >= chars.length()) {
            resultList.push_back(stoi(first));
            resultList.push_back(stoi(second));
            resultList.push_back(stoi(third));
            return true;
        }
 
        // Check if remaining array also satisfies the condition
        bool result = check(chars.substr(offset1), offset2, offset3, max(offset2, offset3), true);
        if (result) {
            resultList.push_front(stoi(first));
        }
        return result;
    }
 
    // If not satisfied, try incrementing third
    if (offset1 + offset2 + offset3 <= chars.length() && (offset3 == max(offset1, offset2) || offset3 == 1 + max(offset1, offset2))) {
        if (check(chars, offset1, offset2, offset3 + 1, false))
            return true;
    }
 
    // If first and second have been finalized, do not
    // alter already computed results
    if (freezeFirstAndSecond)
        return false;
 
    // If first and second are not finalized
    if (offset1 + offset2 + offset3 <= chars.length() && (offset3 == max(offset1, offset2) || offset3 == 1 + max(offset1, offset2))) {
 
        // Try incrementing second
        if (check(chars, offset1, offset2 + 1, max(offset1, offset2 + 1), false))
            return true;
    }
 
    // Try incrementing first
    if (offset1 + offset2 + offset3 <= chars.length() && (offset3 == max(offset1, offset2) || offset3 == 1 + max(offset1, offset2))) {
        if (check(chars, offset1 + 1, offset2, max(offset1 + 1, offset2), false))
            return true;
    }
    return false;
}
 
int main() {
    string numStr = "11235813";
 
    cout << check(numStr, 1, 1, 1, false) << endl;
    for (int i : resultList) {
        cout << i << " ";
    }
    return 0;
}


Python3




from typing import List
 
resultList = []
 
def check(chars: str, offset1: int, offset2: int, offset3: int, freezeFirstAndSecond: bool) -> bool:
    first = chars[:offset1]
    second = chars[offset1:offset1+offset2]
    third = chars[offset1+offset2:offset1+offset2+offset3]
 
    if int(first) + int(second) == int(third):
        if offset1 + offset2 + offset3 >= len(chars):
            resultList.append(int(first))
            resultList.append(int(second))
            resultList.append(int(third))
            return True
         
        result = check(chars[offset1:], offset2, offset3, max(offset2, offset3), True)
        if result:
            resultList.insert(0, int(first))
        return result
 
    if offset1 + offset2 + offset3 <= len(chars) and (offset3 == max(offset1, offset2) or offset3 == 1 + max(offset1, offset2)):
        if check(chars, offset1, offset2, offset3 + 1, False):
            return True
 
    if freezeFirstAndSecond:
        return False
     
    if offset1 + offset2 + offset3 <= len(chars) and (offset3 == max(offset1, offset2) or offset3 == 1 + max(offset1, offset2)):
        if check(chars, offset1, offset2 + 1, max(offset1, offset2 + 1), False):
            return True
 
    if offset1 + offset2 + offset3 <= len(chars) and (offset3 == max(offset1, offset2) or offset3 == 1 + max(offset1, offset2)):
        if check(chars, offset1 + 1, offset2, max(offset1 + 1, offset2), False):
            return True
    return False
 
def main() -> None:
    numStr = "11235813"
 
    print(check(numStr, 1, 1, 1, False))
    print(resultList)
 
if __name__ == "__main__":
    main()


Javascript




// Javascript program for the above approach
 
let resultList = [];
 
function check(chars, offset1, offset2, offset3, freezeFirstAndSecond) {
   
  // Find substrings according to given offsets
  const first = chars.substring(0, offset1);
  const second = chars.substring(offset1, offset1 + offset2);
  const third = chars.substring(offset1 + offset2, offset1 + offset2 + offset3);
 
   
  // If condition is satisfied for current substrings
  if (parseInt(first) + parseInt(second) === parseInt(third)) {
   
      // If whole string is covered.
    if (offset1 + offset2 + offset3 >= chars.length) {
      resultList.push(parseInt(first));
      resultList.push(parseInt(second));
      resultList.push(parseInt(third));
      return true;
    }
     
    // Check if remaining array also satisfies the condition
    const result = check(chars.substring(offset1), offset2, offset3, Math.max(offset2, offset3), true);
    if (result) {
      resultList.unshift(parseInt(first));
    }
    return result;
  }
 
  // If not satisfied, try incrementing third
  if (offset1 + offset2 + offset3 <= chars.length && (offset3 === Math.max(offset1, offset2) || offset3 === 1 + Math.max(offset1, offset2))) {
    if (check(chars, offset1, offset2, offset3 + 1, false)) {
      return true;
    }
  }
     
  // If first and second have been finalized, do not
  // alter already computed results
  if (freezeFirstAndSecond) {
    return false;
  }
 
  // If first and second are not finalized  
  if (offset1 + offset2 + offset3 <= chars.length && (offset3 === Math.max(offset1, offset2) || offset3 === 1 + Math.max(offset1, offset2))) {
     
    // Try incrementing second
    if (check(chars, offset1, offset2 + 1, Math.max(offset1, offset2 + 1), false)) {
      return true;
    }
  }
 
  // Try incrementing first 
  if (offset1 + offset2 + offset3 <= chars.length && (offset3 === Math.max(offset1, offset2) || offset3 === 1 + Math.max(offset1, offset2))) {
    if (check(chars, offset1 + 1, offset2, Math.max(offset1 + 1, offset2), false)) {
      return true;
    }
  }
 
  return false;
}
 
// Driver code main function
function main() {
  const numStr = "11235813";
 
  console.log(check(numStr, 1, 1, 1, false));
  console.log(resultList);
}
 
main();
 
 
// This code is contributed by codebraxnzt


C#




// C# program for the above approach
 
using System;
using System.Collections.Generic;
 
public class SumArray {
    private static LinkedList<int> resultList = new LinkedList<int>();
 
    private static bool Check(char[] chars, int offset1, int offset2, int offset3, bool freezeFirstAndSecond) {
        int first = IntOf(SubArr(chars, 0, offset1));
        int second = IntOf(SubArr(chars, offset1, offset2));
        int third = IntOf(SubArr(chars, offset1 + offset2, offset3));
 
        if (first + second == third) {
            if (offset1 + offset2 + offset3 >= chars.Length) {
                resultList.AddLast(first);
                resultList.AddLast(second);
                resultList.AddLast(third);
                return true;
            }
 
            bool result = Check(SubArr(chars, offset1, chars.Length - offset1), offset2, offset3, Math.Max(offset2, offset3), true);
            if (result) {
                resultList.AddFirst(first);
            }
            return result;
        }
 
        if (IsValidOffSet(offset1, offset2, 1 + offset3, chars.Length)) {
            if (Check(chars, offset1, offset2, 1 + offset3, false)) {
                return true;
            }
        }
 
        if (freezeFirstAndSecond) {
            return false;
        }
 
        if (IsValidOffSet(offset1, 1 + offset2, Math.Max(offset1, 1 + offset2), chars.Length)) {
            if (Check(chars, offset1, 1 + offset2, Math.Max(offset1, 1 + offset2), false)) {
                return true;
            }
        }
 
        if (IsValidOffSet(1 + offset1, offset2, Math.Max(1 + offset1, offset2), chars.Length)) {
            if (Check(chars, 1 + offset1, offset2, Math.Max(1 + offset1, offset2), false)) {
                return true;
            }
        }
 
        return false;
    }
 
    private static bool IsValidOffSet(int offset1, int offset2, int offset3, int length) {
        return (offset1 + offset2 + offset3 <= length && (offset3 == Math.Max(offset1, offset2) || offset3 == 1 + Math.Max(offset1, offset2)));
    }
 
    private static char[] SubArr(char[] chars, int index, int offset) {
        int trueOffset = Math.Min(chars.Length - index, offset);
        char[] destArr = new char[trueOffset];
        Array.Copy(chars, index, destArr, 0, trueOffset);
        return destArr;
    }
 
    private static int IntOf(params char[] chars) {
        return int.Parse(new string(chars));
    }
 
    public static void Main(string[] args) {
        string numStr = "11235813";
        char[] chars = numStr.ToCharArray();
        Console.WriteLine(Check(chars, 1, 1, 1, false));
        Console.WriteLine(string.Join(", ", resultList));
    }
}
 
       
// This code is contributed by princekumaras


Output:

true
[1, 1, 2, 3, 5, 8, 13]

Time Complexity: O(n)
Auxiliary Space: O(n)



Last Updated : 09 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads