前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >经典算法:不大于N的特殊数字

经典算法:不大于N的特殊数字

作者头像
codename_cys
发布2022-08-23 11:20:11
3400
发布2022-08-23 11:20:11
举报
文章被收录于专栏:我的充电站

1. 题目描述

这个题目其实来自于Leetcode的以下两道题目:

  1. 1012. Numbers With Repeated Digits
  2. 2376. Count Special Integers

问题的主体就是,给出一个确定的整数n,求取所有不大于n的,且各个位数都不相同的数的个数。

或者相反,求出存在至少有两位数字相同的数字的个数,不过这两个问题是互补的,所以我们只需要考虑上一个问题即可。

2. 算法思路

这一题的算法思路算是一个相对复杂一点的分类讨论:

  1. 首先,如果生成的数字位数小于n,那事实上就是一个简单的排列组合问题,除了首数字不能为0之外,就没有什么特殊情况了;
  2. 然后要考虑一下位数相同的情况,此时又需要分两类进行考察
    1. 首先是第一位比目标数小的情况,此时后面就是一个完全的排列问题,还是比较好处理的;
    2. 然后就是临界情况,即第一位与目标值相同的情况,此时我们就需要考察第二位的情况,然后此时就又一次回到了这一段开头的情况。
  3. 另外还有一个比较特殊的情况就是如果这个数存在两个位数是相同的情况下,此时跳出循环即可。

3. 代码实现

具体到实现上,我们摘录某位大佬的代码实现如下:

代码语言:javascript
复制
class Solution:
    def countSpecialNumbers(self, n: int) -> int:
        nums = [int(i) for i in str(n+1)] 
        d = len(nums) 
        res = 0 
        
       
        for i in range(1,d):
            res += 9 * math.perm(9,i-1)
        
		
        for i, x in enumerate(nums):
            if i == 0:
                digit_range = range(1,x) 
            else:
                digit_range = range(x)
                
            for y in digit_range:
                if y not in nums[:i]:
                    res += math.perm(9-i,d-1-i)
            if x in nums[:i]: break
                
        return res
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目描述
  • 2. 算法思路
  • 3. 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档