2.21 只考加法的面试题

2.21 只考加法的面试题

算法要求输出64位正整数范围内不能由连续整数相加而成的整数,本文试图采用穷举法搜索出满足条件的整数

###代码1

lim = 800
def fixout(base,lim):#多少连续相加的数,第一个数字是多少
        seq = []
        for i in range(lim):
                a = base * i + base * (base - 1) / 2
                seq.append(a)
        return seq
outseq = []
for i in range(lim):
        outseq.append(i)

for j in range(len(outseq)):
        print '**'
        for jj in range(2,lim):#2-13个连续的数字相加
                for jjj in range(len(fixout(jj,lim))):
                        aa = fixout(jj,lim)
                        if outseq[j] == aa[jjj]:
                                outseq[j] = 0
print outseq

代码1的代码段有4层嵌套,逻辑为构建一个递增列表和一个条件满足列表,逐一检查两个列表中是否有重合,重合则置0,复杂度为O(n^4),效率不高

###代码2

b = 0
def fixout(base,i):
        return base * i + base * (base - 1) / 2
        
outseq = []
for i in range(520):
        outseq.append(i)

for j in range(lim):
        b += 1
        print b
        for jj in range(2,lim):
                for jjj in range(1,lim):
                        if outseq[j] == fixout(jj,jjj):
                                outseq[j] = '-'
print outseq
#print range(1,a)

代码2简化了fixout函数,不再构建条件满足列表,直接运算比较,复杂度降低到O(n^3)

###代码3

b = 0#显示程序在运行
base = 2#从2个连续的数相加开始
lim = 8200#穷举的上限
outseq = []
for i in range(lim):
        outseq.append(i)
a=len(outseq)

def isok(num,base,lim):
        for i in range(lim):
                if (base * i + base * (base - 1) / 2) > lim:
                        break
                else:
                        if (base * i + base * (base - 1) / 2) == num:
                                return False
        return True
                        
                
def remove(seq,base):
        for jj in range(len(seq)):
                if not isok(seq[jj],base,lim):
                        seq[jj] = 0
        for i in seq:
                if i == 0:
                        seq.remove(i)
for base in range(2,lim):
        b += 1
        print b
        remove(outseq,base)

print outseq
              

归纳发现两个连续的数相加产生的数最多,通过逐步删除原列表中不满足要求的数可以大幅降低后面循环的运算量,进而提高运算效率。

###算法结论

8197
8198
[2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]

验证了8200以内的所有数字,以上结果推测答案为2^n,数学证明后面补充。(可用反证法?)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值