2

I was able to solve the problem given in the title using a recursive DP, but got TLE. This was due to the fact that the input string can have about 5000 digits which leads to a lot of sub function calls, and my program is not able to compute the result, even on my on computer.

The question is as follows: ACODE

My solution is the following:

import sys

def chk(word):
    if word[0] == '0':
        return 0
    if int(word) < 27 and int(word) > 0:
        return 1
    else:
        return 0

def dp(line):
    if len(line) > 2:
        return chk(line[0])*dp(line[1:]) + chk(line[:2])*dp(line[2:])
    elif len(line) > 1:
        return chk(line[0])*dp(line[1]) + chk(line)
    else:
        return chk(line)

line = sys.stdin.readline().strip()
while line != '0':
    print dp(line) 
    line = sys.stdin.readline().strip()

Searching the internet leads to the following solution:

1) Initialize an Array of Size N with 0 and element 0 as 1
2) Loop through all the elements
3) If it is a valid single digit number, Copy the previous element's value to the current element (DP[i] = DP[i-1])
4) If it is a valid two digit number, Add the previous to previous element's value to the current element (DP[i] += DP[i-2])

In one line : DP[i] = DP[i-1] {if valid single digit number} + DP[i-2] {if current and previous elements make a valid two digit number}

I'm not sure if I'm doing the same thing, because I'm not able to understand the above approach, or if there is someway to turn my recursive approach to iterative.

4
  • You are not doing the same thing. Your algorithm has an exponential runtime complexity, because you don't memoize results for subproblems (and instead recompute them over and over again). Commented Nov 26, 2013 at 13:48
  • How can I memoize the results in this case? Commented Nov 26, 2013 at 13:53
  • @KartikAnand take a look at my answer for memoizations as suggested by Niklas. Commented Nov 26, 2013 at 13:57
  • You should use indices to represent prefixes of your string instead of strings, otherwise you will probably run out of memory and time even if you add memoization. Commented Nov 26, 2013 at 14:06

2 Answers 2

1

The algorithm is following a Dynamic Programming approach.

It just scans the code-string from left to right.

As the length of string increases, so will the number of possibilities.

Each new digit can have two possibilities. If it is a valid digit, then the new number of possibilities is at least equal to the possibilities upto the previous digit.

Also, if the new digit and prev-digit make a number >= 11 and <= 26, then the number of possibilities increase by (possibilities upto I-2)

Example if the number is 2134

A[0] = 1.
second digit is 1. Hence A[1] is at least = A[0] = 1. 
Also, 21 can make a valid character code as well. 
Hence, A[1] becomes 1 + 1 = 2.

The two strings possible upto A[1] are 2,1 and 21.

Third digit is 3. Hence A[2] is at least = A[1] = 2. 
Also, 13 can make a valid character code.
Hence additional possibilities can result if we consider 13 as a single character = A[2].
Hence A[3] = 2 + 1 = 3 ({2,1,3}, {21,3}, {2,13})

Simililarly for A[4].
Sign up to request clarification or add additional context in comments.

4 Comments

Yes I can see that, but I am not able to digest the solution. Can you please elaborate?
Instead of an array A whose indices you are updating, can't I just take a count variable?
@KartikAnand You need to keep track of the count atleast upto 2 characters before as we are using DP[I-2] to calculate DP[I].
Thanks for the explaination
0

2 very small modifications (won't improve efficiency, but more pythonic & better)

def chk(word):
    if word[0] == '0':
        return 0
    elif 0 < int(word) < 27: # notice the elif & multiple comparisons
        return 1
    else:
        return 0

3 Comments

Oh my bad, surely a very bad place! Updated.
It would be even better to not copy strings around (which adds another n factor to the time complexity). Also, you will surely run out of memory here because you can't clear the cache in between runs.
Yup, a very bad idea to cache it like this. Need a different approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.