输入为List(1,2), List(3,4), List(1000), List(5,6), List(100, 1,3), List(99, 4, 5)
。
预期输出为:List(1,2,3,4,5,6,99,100), List(1000)
我尝试使用foldLeft
,但我发现一个循环O(n)
会丢失一些元素。我想知道Scala集合api或方法是否可以用来解决这个难题?此外,如果可能的话,我更愿意更具功能性。
def merge(lists: List[List[Int]]): List[List[Int]] = {
???
}
提前致谢。
答案 0 :(得分:1)
您可以尝试此功能。它也适用于巨大的列表
def merge(input: List[List[Int]]): List[List[Int]] = {
val sets: Set[Set[Int]] = input.map(_.toSet).toSet
def hasIntersect(set: Set[Int]): Boolean =
sets.count(set.intersect(_).nonEmpty) > 1
val (merged, rejected) = sets partition hasIntersect
List(merged.flatten, rejected.flatten).map(_.toList.sorted)
}
merge(List(List(1, 2), List(3, 4), List(1000), List(5, 6), List(100, 1, 3), List(99, 4, 5)))
您将以
格式获得结果res0: List[List[Int]] = List(List(1, 2, 3, 4, 5, 6, 99, 100), List(1000))
如果您有任何疑问,请告诉我。我很乐意澄清它们。
答案 1 :(得分:1)
您需要的只是filter
,toSet
和sorted
函数调用为
def merge(lists: List[List[Int]]): List[List[Int]] = {
val flattenedList = lists.flatten
val repeatedList = lists.filter(list => list.map(x => flattenedList.count(_ == x) > 1).contains(true))
val notRepeatedList = lists.diff(repeatedList)
List(repeatedList.flatten.toSet.toList.sorted) ++ notRepeatedList
}
然后将merge
函数调用为
val lists = List(List(1,2), List(3,4), List(1000), List(5,6), List(100, 1,3), List(99, 4, 5))
println(merge(lists))
会给你
List(List(1, 2, 3, 4, 5, 6, 99, 100), List(1000))
答案 2 :(得分:1)
以下是一个递归解决方案供您参考:
def merge(a:List[List[Int]]):List[List[Int]] = {
a match {
case Nil => Nil
case h::l =>
l.partition(_.intersect(h)!=Nil) match {
case (Nil, _) =>
//No intersect, just merge the rest and add this one
h::merge(l)
case (intersects, others) =>
//It has intersects, merge them to one list and continue merging
merge((h::intersects).flatten.distinct::others)
}
}
}
res9: List[List[Int]] = List(List(1, 2, 100, 3, 4, 99, 5, 6), List(1000))