博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法:数字与位数问题
阅读量:4060 次
发布时间:2019-05-25

本文共 2348 字,大约阅读时间需要 7 分钟。

问题A:

1~N整数中,包含位数1的个数。

dp算法,时间O(log10(N))

假设数字N各个位置上的数组成Arr[n],
dp[i] 表示位置i上的1可以出现的次数。

  • 当Arr[i] > 1 时,i 位置上1出现的次数只与Arr[i]前面的数字有关。

    例如,N=21045中数字4所在位置1出现次数。
    从 00010 到 21019 都是可行的数字,一共2110次,
    可以发现 2110 = (210 + 1)*10
    其中,210是数字4前数字的代数和,10是数字4所在的位数等级。

  • 当Arr[i] == 0时,i 位置上1出现的次数只与Arr[i]前面的数字有关。

    例如,N=21045中数字0所在位置1出现次数。
    从 00100 到 20199 都是可行的数字,一共2100次,
    可以发现 2100 = (21 + 0)*100
    其中,21 是数字0前数字的代数和, 100是数字0所在的位数等级。

  • 当Arr[i] == 1时,i位置上1出现的次数和Arr[i]前后数字都有关系。

    例如,N = 21045 中数字 1 所在位置 1 出现次数。
    从 01000 到 21045 都是可行的数字,一共2045次,
    可以发现,2045 = (2 + 0)*1000 + 45
    其中,2 是数字 1 前数字的代数和, 1000是数字1所在的位数等级,45 是 数字1后数字的代数和。

可以加三个辅助数组加速计算:

sumFront记录位数i之前数字的代数和。
sumBack记录位数i之后位数的代数和。
Base记录位数i的等级。

对于例子N=21045

N 2 1 0 4 5
Base 10000 1000 100 10 1
sumFront 0 2 21 210 2104
sumBack 1045 45 45 5 0

代码如下:


问题B:

数字从0开始首尾相接拼成长字符串,求第n位置上的数字是几?

例如0123456789101112…中第13位数字是1

模拟做法,时间O(log10(N))

当前位数个数k个,k=1

步骤:
1,计算k位数字拼接后的长度L,判断n是否在内,不在n减去长度L,并k++。
2,当n在k位数拼接之内,则n位置一定是100…0到99…9之间某一位数,n/k大致定位n位置所在的数字,通过n%k进一步判断位置。


问题C:

数组中有n个数,把n个数首尾拼接后获得最小的数。

贪心做法,时间O(NlogN)

例如,3,32,321,拼接最小数321323

预处理,把所有数字变一样长,333,322,321,其中,后面缺的数用最后一位补齐,然后排序,将所有数首尾拼接。


问题D:

一个数二进制表示中1的个数

  • 直接位运算,

    正数,减1,&本身,计数一次,直到为0
    负数,看如何处理补码,是否需要换成正数计算。

  • 超自然算法 之 平行算法:

public int fun1(int n){	n = ( n & 0x55555555 ) + ( ( n >> 1 ) & 0x55555555 );	n = ( n & 0x33333333 ) + ( ( n >> 1 ) & 0x33333333 );	n = ( n & 0x0f0f0f0f ) + ( ( n >> 1 ) & 0x0f0f0f0f );	n = ( n & 0x00ff00ff ) + ( ( n >> 1 ) & 0x00ff00ff );	n = ( n & 0x0000ffff ) + ( ( n >> 1 ) & 0x0000ffff );	return n;}
  • MIT hackmem 算法:


问题E:

数组中一个数字出现1次,其他数字出现3次,找出该数字。

统计每个位置上1出现的次数,可以整除3则代表该数字该位置上为0,否则为1。


问题F:

数组中2个数字出现一次,其他都出现两次,找出这两个数字。

所有数字位抑或,结果数字中位置为1的地方表示2个数字位置上一个为1一个为0。

抑或所有该位置上为1的数字,则可以找到第一个数字。

结果数字与第一个数字抑或,则可以找到第二个数字。


问题G:

位运算做加减乘除:

  • 加法:不断做 aa = a^b 和 bb = (a&b) << 1的操作,直到b为0
  • 减法:a+b 等效 a+(-b),注,补码特点在于符号为参与运算,不需要判断符号
  • 乘法:ab = ab0 + ab1(2 ^ 0) + ab2(2 ^ 1) …ab31(2 ^ 31),只要不溢出,无论a,b为正,负,0都是对的。
  • 除法:a/b 其中 ,b不断左移找到a能包含的最大b*(2 ^ ?),对应结果位上置1,a-b*(2 ^ ?)后,b不断左移来找第二个位置1。(注:若a,b为INT_MIN的话,需要特殊处理,其中只有a被除数为INT_MIN情况复杂,如下)

a + 1 b + ( a − a + 1 b × b ) b \frac{a+1}{b} + \frac{(a - \frac{a+1}{b} \times b )}{b} ba+1+b(aba+1×b)


问题H:

一种字符串和数字对应关系,

给定一个字母表,str=[“A”,“B”,“C”],代表A = 1, B=2,C=3,AA=4,AB=5,AC=6,BA=7…

再给一个数字K,则对应字符串是?

由于字母表有三个字母,则是伪三进制,不同长度三进制数可以表示数字数量为,1,3,9,27,81…

数字K依次减去每个位上的数量,直到不够减,从而得到数字K由几个字母组成。

上一步的到剩余数T,再考查T由几个1,3,9,27…组成,

加上K之前每个位置都用了一次,得到最终每个位置上的数量。


转载地址:http://cbwji.baihongyu.com/

你可能感兴趣的文章
分布式应用开发相关的面试题收集
查看>>
简单理解Socket及TCP/IP、Http、Socket的区别
查看>>
利用HTTP Cache来优化网站
查看>>
利用负载均衡优化和加速HTTP应用
查看>>
消息队列设计精要
查看>>
分布式缓存负载均衡负载均衡的缓存处理:虚拟节点对一致性hash的改进
查看>>
分布式存储系统设计(1)—— 系统架构
查看>>
MySQL数据库的高可用方案总结
查看>>
常用排序算法总结(一) 比较算法总结
查看>>
SSH原理与运用
查看>>
SIGN UP BEC2
查看>>
S3C2440中对LED驱动电路的理解
查看>>
《天亮了》韩红
查看>>
Windows CE下USB摄像头驱动开发(以OV511为例,附带全部源代码以及讲解) [转]
查看>>
出现( linker command failed with exit code 1)错误总结
查看>>
iOS开发中一些常见的并行处理
查看>>
iOS获取手机的Mac地址
查看>>
ios7.1发布企业证书测试包的问题
查看>>
如何自定义iOS中的控件
查看>>
iOS 开发百问
查看>>