删除 O(nlogn) 中列表的重复项 [英] remove duplicate of a list in O(nlogn)

查看:39
本文介绍了删除 O(nlogn) 中列表的重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何删除重复的列表?(运行时间为 O(n log n) )例如:'(4 6 1 1 2 3 3 5 6) => '(4 6 1 2 3 5)

How to remove duplicate of a list? (running time is O(n log n) ) ex: '(4 6 1 1 2 3 3 5 6) => '(4 6 1 2 3 5)

 (define (re-dup lst)
   (cond
      ((empty? lst) empty)
      (else
      (define el (first lst))
      (define el-free-lst (filter (lambda (x) (not (= el x))) (rest lst)))
      (cons el (re-dup el-free-lst)))))

这样对吗?

推荐答案

您当前的解决方案是 O(n^2),因为 filter 遍历列表一次 对于原始列表中的每个元素.可以使用具有恒定时间插入和成员资格操作的辅助数据结构编写 O(n) 解决方案,以跟踪已经找到的元素.

Your current solution is O(n^2), because filter traverses the list once for each of the elements in the original list. It's possible to write an O(n) solution using a helper data structure with constant time insertion and membership operations to keep track of the elements that have been found already.

在 Racket 中,我们有一个开箱即用的 set 数据结构,对于 恒定时间操作,实际上需要 O(log N) 时间一组大小为 N"(参见 文档),因此 set-member?set-add 过程将是 O(log n).所以这个使用 Racket 的 set 的实现不是最优的,但我们实现了 O(n log n) 目标:

In Racket, we have an out-of-the-box set data structure which, for constant time operations, "actually requires O(log N) time for a set of size N" (see the documentation), therefore the set-member? and set-add procedures will be O(log n). So this implementation using Racket's set is not optimal, but we achieve the O(n log n) target:

(define (re-dup lst)
  (let loop ((seen (set))
             (lst lst)
             (acc '()))
    (cond ((null? lst)
           (reverse acc))
          ((set-member? seen (car lst))
           (loop seen (cdr lst) acc))
          (else
           (loop (set-add seen (car lst))
                 (cdr lst)
                 (cons (car lst) acc))))))

它按预期工作,以额外的 O(n) 为代价,保留列表中的原始顺序(这是此问题的约束,如注释中所述)反向操作:

It works as expected, preserving the original order in the list (which is a constraint for this problem, as stated in the comments) at the cost of one additional O(n) reverse operation:

(re-dup '(4 6 1 1 2 3 3 5 6))
=> '(4 6 1 2 3 5)

这篇关于删除 O(nlogn) 中列表的重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆