C# 代码片段
var dict = new Dictionary<int, HashSet<List<int>>>();
foreach (List<int> list2 in two) {
foreach (int i in list2) {
if(dict.ContainsKey(i) == FALSE) {
dict.Add(i, new HashSet<List<int>>());
}
dict[i].Add(list2);
}
}
foreach (List<int> list1 in one) {
HashSet<List<int>> listsInTwoContainingList1 = null;
foreach (int i in list1) {
if (listsInTwoContainingList1 == null) {
listsInTwoContainingList1 = new HashSet<List<int>>(dict[i]);
} else {
listsInTwoContainingList1.IntersectWith(dict[i]);
}
if(listsInTwoContainingList1.Count == 0) {
break;
}
}
foreach (List<int> list2 in listsInTwoContainingList1) {
}
}
例子
L2= {
L2a = {10, 20, 30, 40}
L2b = {30, 40, 50, 60}
L2c = {10, 25, 30, 40}
}
L1 = {
L1a = {10, 30, 40}
L1b = {30, 25, 50}
}
在代码的第一部分之后:
dict[10] = {L2a, L2c}
dict[20] = {L2a}
dict[25] = {L2c}
dict[30] = {L2a, L2b, L2c}
dict[40] = {L2a, L2b, L2c}
dict[50] = {L2c}
dict[60] = {L2c}
在代码的第二部分:
L1a: dict[10] n dict[30] n dict[40] = {L2a, L2c}
L1b: dict[30] n dict[25] n dict[50] = { }
所以L1a
包含在L2a
和L2c
中,但L1b
没有包含在其中。
复杂度
现在关于算法的复杂度,假设L1
有n1
个元素,L2
有n2
个元素,L1
子列表的平均元素数量为m1
,L2
子列表的平均元素数量为m2
。那么:
原始解决方案为:O(n1 x n2 x m1 x m2)
,如果containsSetOf方法使用嵌套循环,则最好的情况是O(n1 x n2 x (m1 + m2))
,如果使用HashSet,则为最佳情况。Is7aq的解决方案也是O(n1 x n2 x (m1 + m2))
。
建议的解决方案为:O(n2 x m2 + n1 x (m1 x nd + n2))
,其中nd
是集合dict[i]
的平均元素数量。
建议方案的效率在很大程度上取决于nd
的值:
IsSubSet()
方法,但问题不在这里。但我仍然必须将每个元素与另一个元素进行比较,这是 N^2 的时间复杂度。也许我误解了你的解决方案。你能提供代码示例吗? - John LathamList<HashSet<T>>
将提高执行时间。在适当的集合上,子集比列表便宜得多。您还可以考虑使用索引。 - Mike Bailey