Reputation: 2393
I am trying to solve Two sum problem using scala
val list = List(1,2,3,4,5)
val map = collection.mutable.Map.empty[Int, Int]
val sum = 9
for {
i <- 0 until list.size
} yield {
map.get(sum - list(i)) match {
case None => map += (list(i) -> i)
case Some(previousIndex) => println(s" Indexes $previousIndex $i")
}
}
Can anyone suggest an O(n) solution without using mutable map using scala
Upvotes: 0
Views: 217
Reputation: 1142
You can try something as follows for the first result:
object Solution extends App {
def twoSums(xs: List[Int], target: Int): Option[(Int,Int)] = {
@annotation.tailrec def go(zipped: List[(Int,Int)], map: Map[Int,Int] = Map.empty): Option[(Int,Int)] = {
zipped match {
case Nil => None
case (ele, idx) :: tail =>
map.get(target - ele) match {
case Some(prevIdx) => Some((prevIdx, idx))
case None => go(tail, map + (ele -> idx))
}
}
}
go(xs.zipWithIndex)
}
val res = twoSums(List(1,2,3,4,5), 9)
println(res)
}
Or via foldLeft
for all results:
object Solution extends App {
def twoSums(xs: List[Int], target: Int): List[(Int, Int)] = {
xs.zipWithIndex.foldLeft((Map.empty[Int,Int], List.empty[(Int,Int)])) {
case ((map, results), (ele, idx)) =>
map.get(target - ele) match {
case Some(prevIdx) =>(map, (prevIdx, idx) :: results)
case None => (map + (ele -> idx), results)
}
}
}._2
val res = twoSums(List(1,2,3,4,5), 9)
println(res)
}
Upvotes: 0
Reputation: 4063
If you are trying to solve "Two sum problem" - meaning you need from given list find two numbers which gives sum equal to given, can go with:
val list = List(1,2,3,4,5)
val sum = 9
val set = list.toSet
val solution = list.flatMap { item =>
val rest = sum - item
val min = Math.min(item, rest)
val max = Math.max(item, rest)
if (set(rest)) Some(min, max) else None
}.toSet
println(solution)
Print result:
Set((4,5))
ScalaFiddle: https://scalafiddle.io/sf/LA6P3eh/0
UPDATE The result required to return indices not values:
val list = List(1,2,3,4,5)
val sum = 9
val inputMap = list.zipWithIndex.toMap
val solution = list.zipWithIndex.flatMap { case (item, itemIndex) =>
inputMap.get(sum - item).map { restIndex =>
val minIndex = Math.min(itemIndex, restIndex)
val maxIndex = Math.max(itemIndex, restIndex)
minIndex -> maxIndex
}
}.toSet
println(solution)
Printout: Set((3,4))
ScalaFiddle: https://scalafiddle.io/sf/LA6P3eh/1
Upvotes: 1