[英]C# - Best Way to Match 2 items from a List Without Nested Loops
我的目標是:對於任何給定的flightDuration,我都想匹配我的filmDurations中的2部電影,它們的總和距飛行30分鍾完全結束。
例如 :
我可以用嵌套循環來做到這一點。 但這是無效的,而且很耗時。
我想更有效地做。 我以為使用Linq,但它仍然是O(n ^ 2)。
最好的有效方法是什么?
編輯:我想清除一件事。
我想在以下位置找到filmDurations [i] + filmDurations [j];
filmDurations [i] + filmDurations [j] == fligtDuration-30
並說我有很長的電影時光。
您可以對所有持續時間進行排序(刪除重復項)( O(n log n) ),然后對它們進行迭代(直到飛行持續時間-30為止)。 搜索第二部電影的相應長度( O(log n) )。
這樣,您可以在O(n log n)中獲得所有持續時間對。
您還可以使用HashMap (持續時間->電影)查找匹配對。
這樣,您可以避免排序和二進制搜索。 遍歷所有持續時間,如果有持續時間=(飛行持續時間-30)的條目,則在地圖中查找。
填充地圖需要O(n)查找O(1),並且您需要迭代所有持續時間。
->在所有復雜度O(n)上,但是您失去了找到“幾乎匹配的對”的可能性,使用上述排序列表方法很容易實現)
正如張雷森所說,您可以將所有項目都放入字典中。 完成后,重寫您的方程式
filmDurations[i] + filmDurations[j] == fligtDuration - 30
如
filmDurations[i] == (fligtDuration - 30 - filmDurations[j])
現在,對於filmDurations
每個項目,在filmDurations
搜索(fligtDuration - 30 - filmDurations[j])
。 如果找到了此類物品,您有解決方案。
接下來的代碼實現了這個概念
public class IndicesSearch
{
private readonly List<int> filmDurations;
private readonly Dictionary<int, int> valuesAndIndices;
public IndicesSearch(List<int> filmDurations)
{
this.filmDurations = filmDurations;
// preprocessing O(n)
valuesAndIndices = filmDurations
.Select((v, i) => new {value = v, index = i})
.ToDictionary(k => k.value, v => v.index);
}
public (int, int) FindIndices(
int flightDuration,
int diff = 30)
{
// search, also O(n)
for (var i = 0; i < filmDurations.Count; ++i)
{
var filmDuration = filmDurations[i];
var toFind = flightDuration - filmDuration - diff;
if (valuesAndIndices.TryGetValue(toFind, out var j))
return (i, j);
}
// no solution found
return (-1, -1); // or throw exception
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.