字典序(今日头条2017秋招真题)

给定整数n和m,将1到n的这n个整数按字典序排列之后,求其中的第m个数字。
对于n = 11,m = 4,按字典序排列依次为1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9,因此第4个数字为2。

输入
输入仅包含两个整数n和m。
样例输入
11 4
输出
输出仅包括一行,即所求排列中的第m个数字。
样例输出
2

这道题又是一道Trie数问题
既然是字典序,那么很自然,我们可以考虑使用字典树来实现,但是,这里并不需要真的生成这个字典树,而只需要计算对应分支的节点数就行了。
1. 首先从1开始,如果1分支的节点数>m,那么第m个数肯定是以1开头,进一步搜索其子节点,搜索子节点时不用再搜索1了,所以是搜索1分支的第m-1个节点。
2. 如果1分支的节点数

#include<iostream>
#include<vector>
using namespace std;

long long getCountOfstart(long long start, long long n)//找到小于n的,以ret开头的树的个数
{
    long long base =1,count = 0;
    while(n>=(start+1)*base -1)
    {
        count += base;
        base = base*10;
    }
    if(n >= start*base )
        count += n-start*base+1;
    return count;
}

long long getNum(long long m,long long n)
{
    long long k = 1;
    while(m!=0)
    {
       long long count = getCountOfstart(k, n);
       if(count >= m)//当子节点数大于等于m时,第m个数就在子节点中寻找,res*10为子节点的第一个,m递减1,直到m=0就找到了那个数 
       {
           m--;
           if(m==0)
               break;
           k = k*10;
       }
       else//当子节点数小于m时,第m个数就要在右边的节点中寻找子节点,m减掉当前子节点数,结果加1就到了右边相邻的节点 
       {
           k++;
           m = m -count;
       }
    }
    return k;
}
int main()
{
    long long n,m;//这里数据类型都要是64位的long long,所以今日头条的题还是很变态的,数据量真大
    cin>>n>>m;
    cout<<getNum(m,n)<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值