Scala Cheatsheet for LeetCode
0. Before You Start
- Since Scala provides immutable collections by default, add this import at the top of every solution that uses mutable collections.
- Import math package for
min, max and common math functions.
- We use Scala3 syntax for control flows so no parentheses (more Python-like)
import scala.collection.mutable._
import scala.math._
1. Data Structure Mapping
| Concept |
Java |
Python |
Scala |
| Fixed array |
int[] |
list |
Array[Int] |
| Tuple |
— |
tuple |
(Int, Int) |
| Dynamic array |
ArrayList<T> |
list |
ArrayBuffer[T] |
| Map |
Map<K,V> |
dict |
Map[K,V] |
| Set |
Set<T> |
set |
Set[T] |
| Queue (BFS) |
LinkedList<T> |
collections.deque |
ArrayDeque[T] |
| Stack |
Deque<T> |
list |
ArrayDeque[T] |
| Min-heap |
PriorityQueue<T> |
heapq |
PriorityQueue[T]()(Ordering[T].reverse) |
| Max-heap |
PriorityQueue<T> (reversed) |
heapq (negated) |
PriorityQueue[T]() |
| Sorted map |
TreeMap<K,V> |
sortedcontainers.SortedDict |
TreeMap[K,V] |
2. Variables & Types
val x = 5
var i = 0
val s: String = "hello"
val arr: Array[Int] = Array(1, 2, 3)
val big = Int.MaxValue
val small = Int.MinValue
3. Control Flow
val result = if x > 0 then "pos" else "neg"
for i <- 0 until n do ()
for i <- 0 to n do ()
for i <- n-1 to 0 by -1 do ()
var i = 0
while i < n do i += 1
import scala.util.control.Breaks._
breakable {
for i <- 0 until n do
if arr(i) == target then break()
}
4. Pattern Matching
Replaces switch and is much more powerful:
x match {
case 0 => "zero"
case 1 | 2 => "one or two"
case n if n < 0 => "negative"
case _ => "other"
}
val pair = (1, "hello")
pair match {
case (n, s) => println(s"$n and $s")
}
map.get("key") match {
case Some(v) => println(v)
case None => println("missing")
}
5. Functional Idioms
arr.map(_ * 2)
arr.filter(_ % 2 == 0)
arr.reduce(_ + _)
arr.foldLeft(0)(_ + _)
List(List(1,2), List(3,4)).flatten
arr.flatMap(x => Array(x, x * 2))
val a = Array(1, 2, 3)
val b = Array("a", "b", "c")
a.zip(b)
arr.zipWithIndex.foreach { case (v, i) => println(i, v) }
arr.sliding(2).toList
(1 to 9).grouped(3).toList
arr.distinct
arr.toSet
Array(1, 2, 3).mkString(", ")
arr.forall(_ > 0)
arr.exists(_ < 0)
arr.take(3)
arr.drop(2)
arr.takeWhile(_ < 5)
6. Arrays
val arr = Array(1, 2, 3)
val zeros = Array.fill(5)(0)
val grid = Array.fill(3, 4)(0)
arr(0)
arr(0) = 10
arr.length
arr.size
arr.sum
arr.max
arr.min
arr.slice(1, 3)
for x <- arr do println(x)
arr.foreach(println)
arr.map(_ * 2)
arr.filter(_ > 1)
arr.indexOf(3)
arr.contains(3)
7. Strings
val s = "hello"
s.length
s(0)
s.substring(1, 3)
s.toCharArray
s.split(" ")
s.trim
s.toUpperCase
s.toLowerCase
s.reverse
s.count(_ == 'l')
s.replace("l", "r")
s.contains("ell")
s.startsWith("he")
'a'.toInt
97.toChar
'a' - 'a'
val sb = new StringBuilder
sb.append("hello")
sb.append(' ')
sb.append("world")
sb.toString
Array('h','i').mkString
List("a","b","c").mkString(", ")
8. HashMap
val map = HashMap[String, Int]()
map("key") = 1
map.get("key")
map("key")
map.getOrElse("key", 0)
map.contains("key")
map.remove("key")
for (k, v) <- map do println(s"$k -> $v")
map.foreach { case (k, v) => println(k, v) }
val freq = s.groupBy(identity).mapValues(_.length)
map.keys
map.values
map.toList
9. HashSet
val set = HashSet[Int]()
set.add(1)
set += 1
set -= 1
set.contains(1)
set.remove(1)
set.size
val vowels = Set('a', 'e', 'i', 'o', 'u')
vowels('a')
10. Queue (BFS)
val q = Queue[Int]()
q.enqueue(1)
q.enqueue(2, 3)
q.dequeue()
q.front
q.isEmpty
q.size
val queue = Queue[(Int, Int)]()
queue.enqueue((start, 0))
val visited = HashSet[Int]()
while queue.nonEmpty do
val (node, dist) = queue.dequeue()
if !visited.contains(node) then
visited.add(node)
for neighbor <- getNeighbors(node) do
queue.enqueue((neighbor, dist + 1))
11. Stack
val stack = Stack[Int]()
stack.push(1)
stack.pop()
stack.top
stack.isEmpty
val stk = ArrayBuffer[Int]()
stk.append(1)
stk.last
stk.remove(stk.size - 1)
12. Priority Queue (Heap)
val maxHeap = PriorityQueue[Int]()
maxHeap.enqueue(3, 1, 4)
maxHeap.dequeue()
val minHeap = PriorityQueue[Int]()(Ordering[Int].reverse)
minHeap.enqueue(3, 1, 4)
minHeap.dequeue()
val pq = PriorityQueue[(Int, Int)]()(Ordering.by(-_._1))
pq.enqueue((5, 0))
val (dist, node) = pq.dequeue()
13. Sorting
arr.sorted
arr.sortWith(_ > _)
arr.sortBy(x => -x)
val pairs = Array((1,3),(2,1),(3,2))
pairs.sortBy(_._2)
pairs.sortWith((a,b) => a._2 < b._2)
scala.util.Sorting.quickSort(arr)
list.sorted
list.sortBy(_.length)
14. Math & Bit Operations
math.abs(-5)
math.max(a, b)
math.min(a, b)
math.pow(2, 10).toInt
math.sqrt(16.0)
7 / 2
7 % 2
n & 1
n >> 1
n << 1
n ^ m
~n
Integer.bitCount(n)
Integer.toBinaryString(n)
val l: Long = 1L << 40
15. Common Algorithm Templates
Binary Search
var lo = 0
var hi = arr.length - 1
while lo <= hi do
val mid = lo + (hi - lo) / 2
if arr(mid) == target then return mid
else if arr(mid) < target then lo = mid + 1
else hi = mid - 1
DFS (recursive)
val visited = HashSet[Int]()
def dfs(node: Int): Unit =
if visited.contains(node) then return
visited.add(node)
for neighbor <- graph(node) do dfs(neighbor)
Dynamic Programming
val dp = Array.fill(n + 1)(0)
dp(0) = 1
for i <- 1 to n do
dp(i) = dp(i - 1) + (if i >= 2 then dp(i - 2) else 0)
16. Gotchas for Python/Java Developers
| Situation |
Pitfall |
Fix |
| Array access |
arr[i] → compile error |
Use arr(i) |
| Missing map key |
map("key") throws |
Use map.getOrElse("key", 0) |
| Mutable collections |
Forgot mutable. prefix |
import scala.collection.mutable._ |
| Int overflow |
Int max ~2.1B |
Use Long for large products/sums |
| Heap direction |
Default PQ is max-heap |
Pass Ordering[T].reverse for min-heap |
== on objects |
Works correctly (unlike Java) |
Safe to use == for value equality |
return in lambdas |
Returns from enclosing method |
Avoid return inside map/foreach |
| Empty collection |
.max on empty throws |
Guard with .nonEmpty or use reduceOption |
until vs to |
Off-by-one |
0 until n = [0,n), 0 to n = [0,n] |