找出列表中的元素对升序排列

2020-09-09 12:00:57 +08:00
 oneTimeElastic

如果有输入 a₁, ..., aₙ, n 为偶数且 aᵢ ∈ ℝ. 使用曼哈顿距离为距离方程,即 dis(aᵢ, aⱼ) = | aᵢ − aⱼ |. 输出应为列表中的 n/2 个元素对,以距离升序排列。

如 input [1, 0.4, 3, 1.1], output [(1, 1.1), (0.4, 3)].

input [1, 0.1, 2, 2.4, 3, 4, 1.5], output [(2, 2.4), (1, 1.5), (3, 4)].

我自己想是用笨办法算出所有 C(n,2)的组合计算距离再排列。

def not_in_pair_of_list(i, ls):
    return not i in [p[0] for p in ls] + [p[1] for p in ls]

def calc(ls):
    ls = sorted(ls)
    d ={}
    for idx1, i in enumerate(ls[:-1]):
        for idx2, j in enumerate(ls[idx1+1:], idx1 + 1):
            d[(i,j)] = j - i
            
    res = []
    for pair in sorted(d, key = lambda k: d[k]):
        i, j = pair
        if not_in_pair_of_list(i, res) and not_in_pair_of_list(j, res):
            res.append(pair)
    return res

ls = [1, 0.1, 2, 2.4, 3, 4, 1.5]
assert calc(ls) == [(2, 2.4), (1, 1.5), (3, 4)]

可这只有 O(n²)。有没有大神支招,看看有没有更快的。我觉得用 minheap 可以,但提取出新元素对时还要重新计算。

1152 次点击
所在节点    算法
5 条回复
EPr2hh6LADQWqRVH
2020-09-09 12:14:39 +08:00
什么乱七八糟的
oneTimeElastic
2020-09-09 12:32:09 +08:00
@avastms 就是对所有的元素的配对,以各元素对的距离排序。但各元素在返回值里只能出现一次。
EPr2hh6LADQWqRVH
2020-09-09 13:39:59 +08:00
sort reverse zip slice
JeffGe
2020-09-09 14:02:33 +08:00
你的代码碰到重复元素就错了
binux
2020-09-09 14:12:00 +08:00
我觉得你看错题了,不然太简单了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/705443

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX