Restore The Array in C++

C++Server Side ProgrammingProgramming

Suppose there is a program that is used to print the array elements of an array A, but there was a little mistake in the program. In that program there was no white space after each element, so if we have one printed string, can we regenerate the array again? We know the array elements are in range 1 to k.

Given the string s and the integer k. We have to find how many number of ways we can restore the array. The answer may be very large so return it modulo 10^9 + 7.

So, if the input is like S = "1318" and k = 2000, then the output will be 8, as we can form 8 different arrays like [1318], [131,8], [13,18],[1,318],[1,3,18],[1,31,8],[13,1,8],[1,3,1,8]

To solve this, we will follow these steps −

  • const int m = 1e9 + 7

  • Define one map dp

  • Define a function add(), this will take a, b,

  • return ((a mod m) + (b mod m)) mod m

  • Define a function help(), this will take idx, s, num, k,

  • if idx >= size of s, then −

    • return 1

  • if idx is in dp and num is in dp[idx], then −

    • return dp[idx, num]

  • ret := 0

  • if num >= 1 and num >= k and s[idx] is not equal to '0', then −

    • ret := add(help(idx, s, 0, k), ret)

  • if num * 10 + (s[idx] - '0') <= k, then −

    • ret := add(help(idx + 1, s, num * 10 + (s[idx] - ASCII of '0'), k), ret)

  • dp[idx, num] := ret

  • return ret

  • From the main method do the following −

  • n := size of s

  • Define an array ans of size n + 1

  • ans[0] := 1

  • s := concatenate one white space before s

  • ks := convert k to string

  • for initialize i := 1, when i <= n, update (increase i by 1), do −

    • cnt := 1

    • temp := blank string

    • for initialize j := i, when j >= 1 and cnt <= 10, update (decrease j by 1), (increase cnt by 1), do −

      • temp := s[j] + temp

      • if s[j] is same as '0', then −

        • Ignore following part, skip to the next iteration

      • if size of temp > size of ks, then −

        • Come out from the loop

      • val := temp as number

      • if val >= 1 and val <= k, then −

        • ans[i] := add(ans[i], ans[j - 1])

  • return ans[n]

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const int m = 1e9 + 7;
class Solution {
   public:
   unordered_map<int, unordered_map<lli, int> > dp;
   lli add(lli a, lli b){
      return ((a % m) + (b % m)) % m;
   }
   int help(int idx, string& s, lli num, int k){
      if (idx >= s.size())
      return 1;
      if (dp.count(idx) && dp[idx].count(num))
      return dp[idx][num];
      int ret = 0;
      if (num >= 1 && num <= k && s[idx] != '0') {
         ret = add(help(idx, s, 0, k), ret);
      }
      if (num * 10 + (s[idx] - '0') <= k) {
         ret = add(help(idx + 1, s, num * 10 + (s[idx] - '0'), k),
         ret);
      }
      return dp[idx][num] = ret;
   }
   int numberOfArrays(string s, int k){
      int n = s.size();
      vector<lli> ans(n + 1);
      ans[0] = 1;
      s = " " + s;
      string ks = to_string(k);
      for (lli i = 1; i <= n; i++) {
         lli cnt = 1;
         string temp = "";
         for (lli j = i; j >= 1 && cnt <= 10; j--, cnt++) {
            temp = s[j] + temp;
            if (s[j] == '0')
               continue;
            if (temp.size() > ks.size())
            break;
            lli val = stol(temp);
            if (val >= 1 && val <= k) {
               ans[i] = add(ans[i], ans[j - 1]);
            }
         }
      }
      return ans[n];
   }
};
main(){
   Solution ob;
   cout << (ob.numberOfArrays("1318",2000));
}

Input

"1318", 2000

Output

8
raja
Updated on 09-Jun-2020 07:21:32

Advertisements