C# 代码 sn-p
var dict = new Dictionary<int, HashSet<List<int>>>();
foreach (List<int> list2 in two) {
foreach (int i in list2) {
if(dict.ContainsKey(i) == FALSE) {
//create empty HashSet dict[i]
dict.Add(i, new HashSet<List<int>>());
}
//add reference to list2 to the HashSet dict[i]
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) { //optimization :p
break;
}
}
foreach (List<int> list2 in listsInTwoContainingList1) {
//list2 contains list1
//do something
}
}
示例
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: