[英]Partitioning a set of values in Python
我編寫了一個函數,試圖將值列表划分為連續的塊。 塊是一組值,其中從頭到尾的值將出現在列表中。 例如,考慮列表[1,2,3,7,7,8,9]
。 這將被分為{1:3, 7:3}
。 以后我可以讀為以interval that starts at 1 of length 3 and an interval that starts at 7 of length 3
。
我想出了以下代碼:-
values = list(set(values))
values.sort()
ranges = {}
for value in values:
if value - i in ranges:
ranges[value-i] += 1
i += 1
else:
i = 1
ranges[value] = 0
我很好奇這是否是最好的方法。 將列表轉換為集合然后重新轉換為列表的時間復雜度是多少? 我猜那將是O(n)。
您對如何更好地做到這一點有任何建議嗎?
我們可以做線性的:
values = [7, 3, 2, 7, 1, 9, 8]
range_by_min, range_by_max = {}, {}
for v in values:
range_by_min[v] = range_by_max[v] = [v, v]
for v in values:
if v - 1 in range_by_max and v in range_by_min:
p, q = range_by_max[v - 1], range_by_min[v]
del range_by_min[q[0]]
del range_by_max[p[1]]
p[1] = q[1]
range_by_max[p[1]] = p
print(range_by_min, range_by_max)
result = {k: v[1] - v[0] + 1 for k, v in range_by_min.iteritems()}
print(result)
結果:
({1: [1, 3], 7: [7, 9]}, {3: [1, 3], 9: [7, 9]})
{1: 3, 7: 3}
這個想法是保留兩個存儲范圍的字典(范圍表示為最小值和最大值的列表)。 第一個將最小鍵映射到范圍。 第二個將最大鍵映射到范圍。
然后遍歷值列表,並加入相鄰范圍。 如果我們訪問的是4,並且有一個范圍4..6,那么我們檢查是否有一個以3結尾的范圍,比方說1..3。 因此,我們將它們加入一個:1..6。
該算法與哈希表訪問呈線性關系。 由於我們希望不斷訪問字典,因此預期的運行時間與值的大小呈線性關系。 通過這種方式,我們甚至不必對輸入數組進行排序。
編輯 :
我看到了David Eisenstat建議的鏈接 。 基於此鏈接,可以將實現更新為僅使用一個字典:
ranges = {v: [v, v] for v in values}
for v in values:
if v - 1 in ranges and v in ranges:
p, q = ranges[v - 1], ranges[v]
if p[1] == v - 1 and q[0] == v:
if q[0] != q[1]:
del ranges[q[0]]
if p[0] != p[1]:
del ranges[p[1]]
p[1] = q[1]
ranges[p[1]] = p
result = {k: v[1] - v[0] + 1 for k, v in ranges.iteritems() if k == v[0]}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.