[英]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
時的余數分組。 然后我們執行以下操作:
0
或k / 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.