topN问题

Posted wdl1078390625

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了topN问题相关的知识,希望对你有一定的参考价值。

 topN问题:给出一个数组,找出前N个最大的元素。

topN问题可以用分治法解决,这个问题与快速排序类似,快速排序是用一个数对数组进行划分,topN问题则不需完成排序,只需划分出前n个最大的数字即可。所以可以采用快排中partition函数的操作,将每次操作的返回值与N作对比,若比N小则对N及其后续的元素继续进行划分,若比N大则对N及其之前的元素进行划分,直到找出N。

该方法的时间复杂度:Θ(n)

示例代码:

import random


def partition(a,i,j):
    if i < j:
        key = random.randint(i,j)
        tmp = a[key]
        a[key] = a[j]
        a[j] = tmp
        k = i-1
        for index in range(i,j):
            if a[index] > a[j]:
                k += 1
                tmp = a[k]
                a[k] = a[index]
                a[index] = tmp
        else:
            k += 1
            tmp = a[k]
            a[k] = a[j]
            a[j] = tmp
            #此处与快排不同,当欲划分的数组元素皆相同时会导致栈溢出,所以当元素相同时
            #返回一个随机下标
            if a[i] == a[j]:
                return random.randint(i,j)
        return k
    return i
            
def find_top_n(a,i,j,top_index):
    top_ret = partition(a,i,j)
    #当返回值比top_index小时,对top_ret及后续元素继续进行划分
    if top_ret < top_index:
        return find_top_n(a,top_ret,j,top_index)
    #当返回值比top_index大时,对top_ret及先前元素继续进行划分
    elif top_ret > top_index:
        return find_top_n(a,i,top_ret,top_index)
    #当返回值等于top_index时,已找到TopN
    else:
        return top_ret


def main(args):
    a = []
    for i in range(10):
        a.append(random.randint(0,100))
    print(a)
    find_top_n(a,0,len(a)-1,5)
    print(a)
    return 0

if __name__ == __main__:
    import sys
    sys.exit(main(sys.argv))

 

以上是关于topN问题的主要内容,如果未能解决你的问题,请参考以下文章

text Hive topN,分组topN问题解决方案

Flink-使用flink处理函数以及状态编程实现TopN案例

Spark 求TopN的优化思路

MapReduce编程初步(WordCount,TopN)

Java实现GroupBy/分组TopN功能

使用dataframe解决spark TopN问题:分组排序取TopN