【发布时间】:2019-11-23 07:03:32
【问题描述】:
我正在尝试解决 HackerRank 上的问题。我试图以更实用的方式解决这个问题(使用不变性)。我尝试了一个解决方案,但我对此并不完全有信心。
这是问题的链接:
我的可变解决方案是这样的:
/**
* Mutable solution
* MSet => mutable set is used
* val pairs => it is delclared var and getting reassigned
*/
import scala.annotation.tailrec
import scala.collection.mutable.{Set => MSet}
def sockMerchant2(n: Int, ar: Array[Int]): Int = {
val sockInventory : MSet[Int] = MSet.empty[Int]
var pairs = 0
ar.foreach { elem =>
if(sockInventory.contains(elem)) {
pairs = pairs + 1
sockInventory -= elem
} else sockInventory += elem
}
pairs
}
sockMerchant(5, Array(1,2,1,2,4,2,2))
同一解决方案的不可变版本:
/**
* Solution with tail recursion.
* Immutable Set is used. No variable is getting reassigned
* How it is getting handled internally ?
* In each iteration new states are assigned to same variables.
* @param n
* @param ar
* @return
*/
import scala.annotation.tailrec
def sockMerchant(n: Int, ar: Array[Int]): Int = {
@tailrec
def loop(arr: Array[Int], counter: Int, sockInventory: Set[Int]): Int ={
if(arr.isEmpty) counter
else if(sockInventory.contains(arr.head))
loop(arr.tail, counter +1, sockInventory-arr.head)
else loop(arr.tail, counter, sockInventory + arr.head)
}
loop(ar, 0, Set.empty)
}
sockMerchant(5, Array(1,2,1,2,4,2,2))
考虑到函数式编程原则,解决这个问题的理想方法是什么?
【问题讨论】:
-
ar.groupBy(identity).map(_._2.length/2).sum -
@jwvh 感谢您的解决方案。它正在通过所有测试用例。我假设“身份”是指生成的 Map 的键。这里数组元素的数据类型是 Int,所以键的域是 Int。这种理解正确吗?
-
没错。
identity表示“按元素的值对元素进行分组”。换句话说,如果a == b那么它们将被组合在一起。 Array#groupBy 类型签名是groupBy[K](f: (T) => K): Map[K,Array[T]]。因为ar是Array[Int],所以groupBy(identity)返回Map[Int, Array[Int]]。
标签: scala functional-programming immutability tail-recursion immutable-collections