例如,假设我有一个排序列表
val sorted = List(1,5,15,37,39,42,50)
最小间隙为(39-37)= 2。我怎样才能获得这个结果?我一直在看foldLeft我感觉它与我需要的相似,但不是很正确
答案 0 :(得分:12)
val sorted = List(1, 5, 15, 37, 39, 42, 50)
sorted match {
case Nil => None
case List(a) => None
case l => Some(l.sliding(2).map{case Seq(a, b) => math.abs(a - b)}.min)
}
// res1: Option[Int] = Some(2)
sliding
返回一个迭代器,因此只能遍历列表一次。
如果您有兴趣找到哪两个元素的间隙最小,您也可以使用minBy。所以这是另一种变化,只是为了好玩。
sorted.view.zip(sorted.tail).minBy(t => math.abs(t._1 - t._2))
// res4: (Int, Int) = (37,39)
答案 1 :(得分:3)
val sorted = List(1, 5, 15, 37, 39, 42, 50)
(sorted.tail,sorted).zipped.map(_-_).min
//res2: Int = 2
<强> [编辑] 强>
您也可以使用折叠:
sorted.tail.foldLeft((sorted.head,Int.MaxValue))((x,y) => (y, math.min(y-x._1,x._2)))._2
答案 2 :(得分:1)
这就是我要做的事情:
编写一个将n个数字列表转换为(n - 1)个间隔列表的函数
编写/使用从列表中选择最小数字的函数
不要忘记处理第1部分的空列表案例! (顺便说一句,第2部分可以写成折叠)。
答案 3 :(得分:1)
使用foldLeft:
sorted match {
case Nil | List(_) => None
case x :: xs => Some(
(xs.foldLeft((Integer.MAX_VALUE, x)) {
case ((min, prev), next) => (math.min(min, next - prev), next)
})._1
)
}
答案 4 :(得分:0)
命令式(可能更快)版本:
if (sorted.isEmpty) {
None
} else {
var sortedTail = sorted.tail
if (sortedTail.isEmpty) {
None
} else {
var minDiff = Int.MaxValue
var prev = sorted.head
do {
val curr = sortedTail.head
minDiff = minDiff min math.abs(curr - prev)
sortedTail = sortedTail.tail
prev = curr
} while (!sortedTail.isEmpty)
Some(minDiff)
}
}