携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。
怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~
一、题目描述:
-
题目内容
-
题目示例
-
题目解析
0 <= n <= 8
二、思路分析:
我们读取本题,题目要求排除各个位存在相同的数字,求出指定数内不同的数字个数。题目要求很明确。那么关于数字范围是怎么样的呢,继续审题:
- 本题给出的参数是:n,计算范围在 0 <= x < 10**n
- n的取值范围在[0,8]
- 每一个数字都是十进制数字
根据以上信息,最简单的方式使用10进制对比每一个各个位的数字是否相等,思路如下:
- for循环遍历10**n范围内的数字i,tmp列表存储数字i的每一位
- 数字i对于10进行取余,当在tmp出现一样时,则same变量+1
- 以此类推,遍历完10n-1个数,则各个位不数字个数则为10n-same
- 以上思路代码使用python实现如下:
但是不幸的是,当n=8时,上述代码会超出时间限制,被无情地NG啦class Solution(object): def countNumbersWithUniqueDigits(self, n): """ :type n: int :rtype: int """ same = 0 for i in range(10**n): tmp = [] while i : cur = i % 10 i = i / 10 if cur in tmp: same +=1 break else: tmp.append(cur) return 10**n - same
那么对于使用十进制分解的方式行不通,则我们只能继续思考新方法,观察和找规律下发现可以直接通过数学方式计算出n的每一位取结果的可能,进行累计➕
- 当n为0时,则不同数字个数为1
- 当n为1时,则不同数字个数为10
- 当n>=2时,最高位取的个数可能为(1~9)9种可能,后面位取数字的可能为9,8,7..等 那么根据规律,我们可以推出公式为:
- f(1) = 10
- f(2) = 10+9*9=91
- f(3) = 10+9 * 9 +9 * 9 * 8
class Solution(object): def countNumbersWithUniqueDigits(self, n): """ :type n: int :rtype: int """ if n == 0: return 1 if n == 1: return 10 cur,ans = 9,10 for i in range(n-1): cur *= 9-i ans += cur return ans -
方法二:打表法
- 由于n范围在0~8之间,则我们可以通过list来存储每种结果,直接通过索引的方式返回结果即可
class Solution(object):
def countNumbersWithUniqueDigits(self, n):
"""
:type n: int
:rtype: int
"""
listn = [1,10,91,739,5275,32491,168571,712891,2345851]
return listn[n]
三、总结:
本题考察对数学排列组合方法应用,在十进制最高位除0外其他9个数,其他位未来每一位数都不一样则依次从9个可能开始递减取出,AC提交记录如下:
- 时间复杂度:O(n),仅使用一个for循环
- 空间复杂度:O(1),使用常量变量
以上是本期内容,欢迎大佬们点赞评论,下期见~~~