簡體   English   中英

從C#中的List的List中提取元素

[英]Extract elements from List of List in C#

我正在嘗試解決 HackerRank 練習“不可分割的子集” https://www.hackerrank.com/challenges/non-divisible-subset/

練習曲目練習曲目是關於創建一個程序,該程序將接受整數列表和數字“k”,並將 output 計算列表中不能被“k”整除且不-重復。

我的問題是結果與預期的 output 不同。您能檢測到我的代碼中有任何問題嗎? 可能這是一個邏輯錯誤,但我被卡住了。 請幫我。

輸入k=9和輸入list = 422346306, 940894801, 696810740, 862741861, 85835055, 313720373 , output 應該是5但我的代碼得到6

public static int nonDivisibleSubset(int k, List<int> s)
    {
        var x = GetPerm(s);


        var y = x.Where(x => x.Value % k != 0).Select(x=>x.Key).ToList();
        var a = y.SelectMany(x => x).ToHashSet();

        return a.Count();

    }

    static Dictionary<List<int>,int> GetPerm (List<int> list)
    {
        Dictionary<List<int>,int> perm = new Dictionary<List<int>, int>();

        for (int i = 0; i < list.Count; i++)
        {
            for (int j = i+1; j < list.Count; j++)
            {
                List<int> sumCouple = new List<int>();
                sumCouple.Add(list[i]);
                sumCouple.Add(list[j]);
                perm.Add(sumCouple, sumCouple.Sum());
            }

        }
        return perm;
    }

正如我所看到的實際問題是完全不同的:

給定一組不同的整數,打印其中任何數字的總和不能被k整除的最大子集的大小。

如果我們看一下這個例子:

list = {422346306, 940894801, 696810740, 862741861, 85835055, 313720373} 
k = 9

我們不能取全部 6 個數字,因為940894801 + 313720373可以被k = 9整除 所需的子集是除最后一項外的所有子集: {422346306, 940894801, 696810740, 862741861, 85835055}

解決方案也會有所不同:

public static int nonDivisibleSubset(int k, List<int> s)
{
    Dictionary<int, int> remainders = s
        .GroupBy(item => item % k)
        .ToDictionary(group => group.Key, group => group.Count());
        
    int result = 0;
    
    foreach (var pair in remainders) {
        if (pair.Key == 0 || pair.Key % (k / 2) == 0 && k % 2 == 0)
            result += 1;
        else if (!remainders.TryGetValue(k - pair.Key, out int count))
            result += pair.Value;
        else if (count < pair.Value)
            result += pair.Value;
        else if (count == pair.Value && pair.Key < k - pair.Key)
            result += pair.Value;
    }   
    
    return result;  
}

這個想法是將所有數字除以k時的余數分組。 然后我們執行以下操作:

  • 如果余數是0k / 2 (對於偶數k ),我們可以只將一個這樣的數字放入子集中
  • 如果余數是x我們可以將所有此類數字或所有具有余數k - x的數字添加到子集。

時間復雜度: O(n)空間復雜度: O(n)

不是問題的答案 - 但您的代碼至少存在一個問題 - List不能按原樣用作字典的鍵,因為它不會覆蓋Equals / GetHashCode ,因此它將執行參考比較。 您可以提供自定義相等比較器:

class PairListEqComparer : IEqualityComparer<List<int>>
{
    public static PairListEqComparer Instance { get; } = new PairListEqComparer();

    public bool Equals(List<int> x, List<int> y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.Count != 2 || y.Count != 2) return false; // or throw

        return x[0] == y[0] && x[1] == y[1];
    }

    public int GetHashCode(List<int> obj) => HashCode.Combine(obj.Max(), obj.Min(), obj.Count);
}

和用法:

Dictionary<List<int>,int> perm = new Dictionary<List<int>, int>(PairListEqComparer.Instance);

或者考慮使用有序值元組(編譯器將生成所需的方法)。 從中你可以考慮優化和更好的算法。

至於解決方案本身——有效的蠻力方法是生成所有大小的所有排列,即從 1 到s.Count並找到滿足條件的最長排列(盡管我懷疑它對 hackerrank 是否足夠有效)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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