Unlucky number 13

前端 未结 6 953
面向向阳花
面向向阳花 2021-01-18 06:37

I came across this problem Unlucky number 13! recently but could not think of efficient solution this.

Problem statement :

N is taken as input.

6条回答
  •  清酒与你
    2021-01-18 07:17

    Thanks to L3viathan's comment now it is clear. The logic is beautiful.

    Let's assume a(n) is a number of strings of n digits without "13" in it. If we know all the good strings for n-1, we can add one more digit to the left of each string and calculate a(n). As we can combine previous digits with any of 10 new, we will get 10*a(n-1) different strings. But we must subtract the number of strings, which now starts with "13" which we wrongly summed like OK at the previous step. There is a(n-2) of such wrongly added strings. So a(n) = 10*a(n-1) - a(n-2). That is it. Such simple.

    What is even more interesting is that this sequence can be calculated without iterations with a formula https://oeis.org/A004189 But practically that doesn't helps much, as the formula requires floating point calculations which will lead to rounding and would not work for big n (will give answer with some mistake).

    Nevertheless the original sequence is quite easy to calculate and it doesn't need to store all the previous values, just the last two. So here is the code

    def number_of_strings(n):
        result = 0
        result1 = 99
        result2 = 10
        if n == 1:
            return result2
        if n == 2:
            return result1
        for i in range(3, n+1):
            result = 10*result1 - result2
            result2 = result1
            result1 = result
        return result 
    

    This one is several orders faster than my previous suggestion. And memory consumption is now just O(n)

    P.S. If you run this with Python2, you'd better change range to xrange

提交回复
热议问题