高程有几道题比较有意思,在这里记录一下。
第一题:大概是在2-61之间的数,如果这个数的因数(不包括它本身)之和等于它本身,称之为完数;若大于它本身,则称之为盈数。如6=3+2+1, 6是完数。12<6+4+3+2+1, 12是盈数。求2-61之间的完数和盈数。
比较简单的思维就是,遍历2-61之间的数,找到每个数的因子,求出来之后跟原数做比较。代码这里就不放了。但是笔者的一个朋友给出了一种新奇的想法,笔者觉得非常有比较纪念一下。代码如下:
A=[1]*61
for i in range(2,31):
j=2*i
while j<=60:
A[j]+=i
j+=i
for i in range(2,61):
if A[i]==i:
print("%d 是完数"%i)
elif A[i]>i:
print("%d 是盈数"%i)
第二题:给一组100以内的数,进行排序。要求时间复杂度为O(n),空间复杂度为O(1)。
分析一下这道题,空间复杂度为O(1),则说明需要是就地排序。时间复杂度为O(n),那么数据结构书上那些经典的排序算法就不要想了。不过基数排序倒是有些接近,但也是不可以直接使用的。
桶排序:建立一堆buckets;遍历原始数组,并将数据放入到各自的buckets当中;对非空的buckets进行排序; 按照顺序遍历这些buckets并放回到原始数组中即可构成排序后的数组。
利用桶排序的思想,可以构造如下算法:
给出大小为100的数组,初始化为全0. 当输入的数与数组的下标+1相等时,对应下标的值加1. 这样依次进行。利用数组中的值来存储一个数重复的次数。然后依次遍历输出即可。
当然这个算法,只能针对有限个数,如果是浮点数或者范围是无限的就无能为力了。但是无妨,锻炼思维,增长见识而已。毕!