|
| 1 | +package sierikov.leetcode.tasks.medium |
| 2 | + |
| 3 | +import scala.annotation.tailrec |
| 4 | +import scala.collection.immutable.Queue |
| 5 | + |
| 6 | +// Leetcode: https://leetcode.com/problems/course-schedule-ii/description/ |
| 7 | +object CourseSheduleII { |
| 8 | + def findOrder(numCourses: Int, prerequisites: Array[Array[Int]]): Array[Int] = { |
| 9 | + val map: Map[Int, Array[Int]] = createMap(prerequisites) |
| 10 | + val starting = Queue.apply(findStarting(numCourses, createMap(prerequisites)).toArray*) |
| 11 | + iterateOverCourses(map, starting) |
| 12 | + } |
| 13 | + |
| 14 | + def createMap(prerequisites: Array[Array[Int]]): Map[Int, Array[Int]] = |
| 15 | + prerequisites.groupMap(_.apply(0))(_.tail.head) |
| 16 | + |
| 17 | + def findStarting(n: Int, map: Map[Int, Array[Int]]): Set[Int] = |
| 18 | + (0 until n).filter(i => map.get(i).isEmpty).toSet |
| 19 | + |
| 20 | + @scala.annotation.tailrec |
| 21 | + def iterateOverCourses( |
| 22 | + map: Map[Int, Array[Int]], |
| 23 | + startingCourses: Queue[Int], |
| 24 | + takenCourses: Vector[Int] = Vector.empty |
| 25 | + ): Array[Int] = startingCourses.dequeueOption match |
| 26 | + case Some((course, queue)) => { |
| 27 | + val removedVertex = map.view.mapValues(_.filter(_ != course)).toMap |
| 28 | + val (coursesWithNoDependencies, otherCourses) = removedVertex.partition(_._2.isEmpty) |
| 29 | + iterateOverCourses( |
| 30 | + otherCourses, |
| 31 | + queue.enqueueAll(coursesWithNoDependencies.keySet), |
| 32 | + takenCourses :+ course |
| 33 | + ) |
| 34 | + } |
| 35 | + case None if map.isEmpty => takenCourses.toArray |
| 36 | + case None => Array.emptyIntArray |
| 37 | +} |
0 commit comments