单号2 Scala解决方案

时间:2017-08-01 21:42:35

标签: algorithm scala

给定一个整数数组,每个元素出现三次,除了一个,只出现一次。找一个单一的。这就是我现在拥有的。但是一旦得到单个数字“b”,我不知道如何打破for循环。请问Scala中的任何解决方案吗?

for(Array(a,b) <- nums.sorted.sliding(2))
{
  if (a == b){j = j+1}
  else 
   {
      if (j < 3) j =1
      b
   }
}

2 个答案:

答案 0 :(得分:3)

这样就可以了。

nums.groupBy(identity).find(_._2.length == 1).get._1

如果没有单计数元素,它会抛出有点不安全。如果在没有找到单计数元素时返回默认值,则可以更安全。

nums.groupBy(identity).find(_._2.length == 1).fold(-1)(_._1)

答案 1 :(得分:0)

另一种方法是通过在基数3模3中添加两个数字的数字来对数组求和(换句话说,在基数3中为XOR)。出现3次的元素将变为零,因此该总和的结果将是单个数字。

def findSingleNumber(numbers: Array[Int]) = {
  def add3(a: String, b: String): String = a.zipAll(b, '0', '0').map {
    case (i, j) => ((i.toInt + j.toInt) % 3 + '0').toChar
  }(collection.breakOut)

  val numbersInBase3 = numbers.map(n => Integer.toString(n, 3).reverse) 
  Integer.parseInt(numbersInBase3.fold("0")(add3).reverse, 3)
}

scala> findSingleNumber(Array(10, 20, 30, 100, 20, 100, 10, 10, 20, 100))
res1: Int = 30

或将基数为3的数字表示为数字数组:

def findSingleNumber(numbers: Array[Int]) = {
  def toBase3(int: Int): Array[Int] =
    Iterator.iterate(int)(_ / 3).takeWhile(_ != 0).map(_ % 3).toArray

  def toBase10(arr: Array[Int]): Int =
    arr.reverseIterator.foldLeft(0)(_ * 3 + _)

  def add3(a: Array[Int], b: Array[Int]): Array[Int] = a.zipAll(b, 0, 0).map {
    case (i, j) => (i + j) % 3
  }

  toBase10(numbers.map(toBase3).fold(Array.empty[Int])(add3))
}