面试之路2019 - 03

日期:

2019-6-20

面试题:

一共考察了两个在线写的面试题:一个偏算法,另一个不是很算法;
如我所料的,偏算法的没有写出来,问题如下:

输入: 一个数字n
求数列【1,2,3,4,5,6,7,8,9,10,11,12,…】这个是一个无限长的数列
在这个数列中,第n个数字是多少?

例如: n等于11的时候,输出为 0, (10,11,12)都是算两个数字

思路:这个题是对应的是 leetcode400 , 难度为easy… 信心受到打击…

搞这个题的时候,说实话,心理还是相当紧张的,因为算法一直不是我的强项,(如果一开始知道这个是easy级别的题目,说不定就没这么紧张了)

太紧张了,所以没有办法展开思维,什么意思的呢?如果看到我草稿就能看出来:

1-9 9个数字 9位
10-99 90个数字 180位

其实再进一步已经可以看出规律了,但是由于我内心预期这个题很难,自我暗示我自己绝对做不出来,所以没有继续往下推演

如果继续推算可以看出:

1-9 9个数字 9位
10-99 90个数字 180位
100-999 900个数字 2700位
1000-9999 9000个数字 36000位

大概推演4次,就可以看出规律了

1-9 9个数字 9位 = 1x9x(10^0)
10-99 90个数字 180位 = 2x9x(10^1)
100-999 900个数字 2700位 = 3x9x(10^2)
1000-9999 9000个数字 36000位 = 4x9x(10^3)
规律位 nx9x10^(n-1)

如果要计算第n位的话,首先要计算这个n落在哪一个区间,比如:是落在 100-999这个区间的哪一个,比如 200 这个数字
200-9-180 = 11

所以是在100-999中的第11位,100到999是由三位组成的,11/3 = 3 11%3 = 2 则 11 位是第4个数字的第二位

即 100 101 102 103 …

即 0

到这里,我还是以为做不出来,但是最终查询了最终的参考方法,思路是这样子滴:

func findNthDigit(n int) int {
    w := 1
    b := 1
    bit := 1 // 位数
    number := 0 // 当前数字
    
    // 这个循环是关键
    for {
        now := w*9*b
        if n > now {
            n -= now
            all += 9*b
            w+=1
            b*=10
            bit+=1
        } 
    }
    
    no := n/bit
    c := n%bit
    
    // 当前数字 = 前面过去的数字数量+这个区间内的数字数量
    cur := all+no+1 // 比如n=0,是这个区间内的第1个数字
    
    // todo 例如当前数字是 289 , 获取第n位的方法,最简单的应该是转字符串,取位再转数字
    
    return result
}

关键没有想明白的,就是这个循环,心里一直否定自己的这个想法,觉得这个想法还是太繁琐了,其实竟然是正确的解决方案,果然是 怯兵必败

你可能感兴趣的:(面试之路,面试问题)