簡體   English   中英

C#-匹配列表中沒有嵌套循環的2個項目的最佳方法

[英]C# - Best Way to Match 2 items from a List Without Nested Loops

  • 假設我有一個列表,其中包含一些int類型表示的電影持續時間的縮影 ,稱為filmDurations
  • 而且我有一個int參數,稱為flightDuration,用於任何給定飛行的持續時間,單位為minitues。

我的目標是:對於任何給定的flightDuration,我都想匹配我的filmDurations中的2部電影,它們的總和距飛行30分鍾完全結束。

例如 :

  • filmDurations = {130,105,125,140,​​120}
  • flightDuration = 280
  • 我的輸出:(130120)

我可以用嵌套循環來做到這一點。 但這是無效的,而且很耗時。

我想更有效地做。 我以為使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM