# 660. Remove 9

**<font color=red>难度: Hard</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/remove-9/

> 内容描述

```
Start from integer 1, remove any integer that contains 9 such as 9, 19, 29...

So now, you will have a new integer sequence: 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, ...

Given a positive integer n, you need to return the n-th integer after removing. Note that 1 will be the first integer.

Example 1:
Input: 9
Output: 10
Hint: n will not exceed 9 x 10^8
```

## 解题方案

> 思路 1
******- 时间复杂度: O(1)******- 空间复杂度: O(1)******

```
Let's write the first numbers and try to notice a pattern. Those numbers are:

1, 2, 3, 4, 5, 6, 7, 8,
10, 11, 12, 13, 14, 15, 16, 17, 18,
20, 21, 22, 23, 24, 25, 26, 27, 28,
...
80, 81, 82, 83, 84, 85, 86, 87, 88,
100, 101, 102, ...

These numbers look exactly like all base-9 numbers!

Indeed, every base-9 number is a number in this sequence, 
and every number in this sequence is a base-9 number. 
Both this sequence and the sequence of all base-9 numbers are in increasing order. 
The answer is therefore just the n-th base-9 number.
```

递归

```python
class Solution:
    def newInteger(self, n):
        """
        :type n: int
        :rtype: int
        """
        return n if n < 9 else 10 * self.newInteger(n // 9) + n % 9
```



> 思路 2
******- 时间复杂度: O(1)******- 空间复杂度: O(1)******


```python
class Solution:
    def newInteger(self, n):
        """
        :type n: int
        :rtype: int
        """
        res = ''
        while n:
            res = str(n % 9) + res
            n //= 9
        return int(res)
```


## Follow up

what if we are not removing 9 but removing 1, 2, 3, ... , 8?


> 思路 1
******- 时间复杂度: O(1)******- 空间复杂度: O(1)******

参考[Alternative solution applicable to the general case](https://leetcode.com/problems/remove-9/discuss/106573/Alternative-solution-applicable-to-the-general-case)

```python
class Solution:
    def newInteger(self, n):
        """
        :type n: int
        :rtype: int
        """

        def count(m, d): # count how many number has 'd' in it in range [1, m]
            res, p, q = 0, 1, 1
            n = m
            while n >= 10:
                n //= 10
                p *= 10
                q *= 9
            n = m
            while n >= d:
                a = n // p
                res += a * (p - q)
                if a == d:
                    res += n % p + 1
                    break
                elif a > d:
                    res += q
                n %= p
                p //= 10
                q //= 9
            return res

        def helper(n, remove):
            pre = cur = 0
            cur = count(n + cur, remove)
            while pre != cur:
                pre = cur
                cur = count(n + cur, remove)
            return int(min(n + cur, float('inf')))

        return helper(n, 9)
```

测试了一下remove 7 的话，第70个 number 是88，测试通过！！




















