例如,假設我有一個排序列表我如何獲得列表元素之間的最小差距?
VAL排序=列表(1,5,15,37,39,42,50)
最小間隙爲(39-37)= 2。我將如何獲得這個結果?我一直在尋找foldLeft我感覺它類似於我所需要的,但不完全正確的事情
例如,假設我有一個排序列表我如何獲得列表元素之間的最小差距?
VAL排序=列表(1,5,15,37,39,42,50)
最小間隙爲(39-37)= 2。我將如何獲得這個結果?我一直在尋找foldLeft我感覺它類似於我所需要的,但不完全正確的事情
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
這裏是我會做:
編寫將N個號碼列表功能成的列表(N - 1)間隙
寫入/使用從列表中選擇最小的數的函數
不要忘記處理空列表殼體F或第1部分! (順便說一句,第2部分可以寫成一個摺疊)。
Can(1)可以在沒有for循環的情況下完成嗎?我試圖使用功能性解決方案@deltanovember – deltanovember
- 當然!有很多純粹的功能方法可以做1。一種方法會使用遞歸! –
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)
勢在必行(可能更快)版本:
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)
}
}
使用折左:
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
)
}
如果它是一個排序的列表,你可以做一個馬特·芬維克在一次迭代中提出的建議。它將花費O(N)時間。 minGap = minGap
Gleeb