算法:设计一个O(n)复杂度的算法,在大量数中找到前10个最大的数

一. 设计一个O(n)复杂度的算法

1、问题:计数排序

  • 现在有一个列表,列表中的数范围都在0到100之间,列表长度大约为100万,设计算法在O(n)时间复杂度内将列表进行排序

2、原理

  • 必须知道这些数中最大的数是多少
  • 然后生成一个长度等于最大数的列表
  • 循环li列表中所有的数,li中每出现一次这个数就在生成的count列表中加一
  • 这样就可以在count列表中的对应位置记录出列表li中所有数出现的次数
  • 然后在循环count,这个数出现几次就依次写几个到li列表中,就出现下面效果

答案:

def count_sort(li, max_num):
   count = [0 for i in range(max_num + 1)]
   for num in li:
      count[num] += 1
   i = 0
   print('count',count)
   for num,m in enumerate(count):        #循环列表count,按顺序得到li中数出现次数
      for j in range(m):            #这个数出现多少次就在li中依次追加多少个
         li[i] = num
         i += 1
li = [3,4,5,3,2,4,5,6,7,4]
count_sort(li,10)
print(li)        #[2, 3, 3, 4, 4, 4, 5, 5, 6, 7]

二. 在大量数中找到前10个最大的数

1、问题

  • 现在有n个数(n>10000),设计算法,按大小顺序得到前世大的数。
  • 应用场景:榜单TOP 10

2、使用插入法解决思路(时间复杂度: O(kn))

  • 先取出待排序列表前11个元素,使用插入排序先有序
  • 然后依次循环未排序的数,一个个的替换TOP 10列表中的第11号元素,再进行一次插入排序
  • 这样仅循环了一次列表即可得到前11大的元素,最后列表切片,切出前10大元素即可

插入法解决:

# 一趟插入
def insert(li,i):
   tmp = li[i]      # tmp是无序区取出的一个数
   j = i - 1        # li[j]是有序区最大的那个数
   while j >= 0 and li[j] < tmp:
      #li[j] < tmp 这个条件的大于号小于号控制是10个最大的数还是最小的数
      li[j + 1] = li[j]  # 将有序区最右边的数向右移一个位置
      j = j - 1
   li[j + 1] = tmp  # 将tmp放到以前有序区最大数的位置,再依次与前一个数比较

def insert_sort(li):
   for i in range(1, len(li)):
      insert(li, i)

def topk(li,k):
   top = li[0:k+1]
   insert_sort(top)                #先将列表中的11个元素用插入法排序
   
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值