You are given an N × N matrix in which every cell is colored black or white. Columns are numbered from 0 to N-1 (from left to right). This coloring is represented by a non-empty array of integers A. If the K-th number in the array is equal to X then the X lowest cells in the K-th column of the matrix are black. The rest of the cells in the K-th column are white. The task is to calculate the side length of the biggest black square (a square containing only black cells).
Write a function:
object Solution { def solution(a: Array[Int]): Int }
that, given an array of integers A of length N representing the coloring of the matrix, returns the side length of the biggest black square.
Examples:
1. Given A = [1, 2, 5, 3, 1, 3], the function should return 2. For example, the black square of side 2 contains the two lowest rows of the 1st and 2nd columns (counting from 0).
2. Given A = [3, 3, 3, 5, 4], the function should return 3. For example, the biggest black square has side 3 and contains the three lowest rows of the last three columns.
3. Given A = [6, 5, 5, 6, 2, 2], the function should return 4. The biggest black square has side 4 and contains the four lowest rows of the first four columns.
Write an efficient algorithm for the following assumptions:
- N is an integer within the range [1..100,000];
- each element of array A is an integer within the range [1..N].
import scala.collection.JavaConverters._
// you can write to stdout for debugging purposes, e.g.
// println("this is a debug message")
case class SizeInfo(_max: Int, current: Int) {
def inc = this.copy(current = current + 1)
def max = Math.max(_max, current)
def reset = SizeInfo(max, 0)
}
object Solution {
def solution(a: Array[Int]): Int = {
def hasSquare(side: Int): Boolean = {
val size = a.foldLeft(SizeInfo(0, 0))((size, x) =>
if (x >= side) size.inc else size.reset
)
size.max >= side
}
def binary(l: Int, r: Int): Int =
if (l >= r) l
else {
val m = ((l + r) / 2) + ((l + r) % 2)
if (hasSquare(m))
binary(m, r)
else
binary(l, m - 1)
}
binary(0, a.length)
}
}
import scala.collection.JavaConverters._
// you can write to stdout for debugging purposes, e.g.
// println("this is a debug message")
case class SizeInfo(_max: Int, current: Int) {
def inc = this.copy(current = current + 1)
def max = Math.max(_max, current)
def reset = SizeInfo(max, 0)
}
object Solution {
def solution(a: Array[Int]): Int = {
def hasSquare(side: Int): Boolean = {
val size = a.foldLeft(SizeInfo(0, 0))((size, x) =>
if (x >= side) size.inc else size.reset
)
size.max >= side
}
def binary(l: Int, r: Int): Int =
if (l >= r) l
else {
val m = ((l + r) / 2) + ((l + r) % 2)
if (hasSquare(m))
binary(m, r)
else
binary(l, m - 1)
}
binary(0, a.length)
}
}
Solution.java:1: warning: '_' used as an identifier import scala.collection.JavaConverters._ ^ (use of '_' as an identifier might not be supported in releases after Java SE 8) Solution.java:1: error: ';' expected import scala.collection.JavaConverters._ ^ Solution.java:6: error: '{' expected case class SizeInfo(_max: Int, current: Int) { ^ Solution.java:7: error: ';' expected def inc = this.copy(current = current + 1) ^ Solution.java:8: error: ';' expected def max = Math.max(_max, current) ^ Solution.java:9: error: ';' expected def reset = SizeInfo(max, 0) ^ Solution.java:12: error: class, interface, or enum expected object Solution { ^ 6 errors 1 warning
import scala.collection.JavaConverters._
// you can write to stdout for debugging purposes, e.g.
// println("this is a debug message")
case class SizeInfo(_max: Int, current: Int) {
def inc = this.copy(current = current + 1)
def max = Math.max(_max, current)
def reset = SizeInfo(max, 0)
}
object Solution {
def solution(a: Array[Int]): Int = {
def hasSquare(side: Int): Boolean = {
val size = a.foldLeft(SizeInfo(0, 0))((size, x) =>
if (x >= side) size.inc else size.reset
)
size.max >= side
}
def binary(l: Int, r: Int): Int =
if (l >= r) l
else {
val m = ((l + r) / 2) + ((l + r) % 2)
if (hasSquare(m))
binary(m, r)
else
binary(l, m - 1)
}
binary(0, a.length - 1)
}
}
import scala.collection.JavaConverters._
// you can write to stdout for debugging purposes, e.g.
// println("this is a debug message")
case class SizeInfo(_max: Int, current: Int) {
def inc = this.copy(current = current + 1)
def max = Math.max(_max, current)
def reset = SizeInfo(max, 0)
}
object Solution {
def solution(a: Array[Int]): Int = {
def hasSquare(side: Int): Boolean = {
val size = a.foldLeft(SizeInfo(0, 0))((size, x) =>
if (x >= side) size.inc else size.reset
)
size.max >= side
}
def binary(l: Int, r: Int): Int =
if (l >= r) l
else {
val m = ((l + r) / 2) + ((l + r) % 2)
if (hasSquare(m))
binary(m, r)
else
binary(l, m - 1)
}
binary(0, a.length)
}
}
import scala.collection.JavaConverters._
// you can write to stdout for debugging purposes, e.g.
// println("this is a debug message")
case class SizeInfo(_max: Int, current: Int) {
def inc = this.copy(current = current + 1)
def max = Math.max(_max, current)
def reset = SizeInfo(max, 0)
}
object Solution {
def solution(a: Array[Int]): Int = {
def hasSquare(side: Int): Boolean = {
val size = a.foldLeft(SizeInfo(0, 0))((size, x) =>
if (x >= side) size.inc else size.reset
)
size.max >= side
}
def binary(l: Int, r: Int): Int =
if (l >= r) l
else {
val m = ((l + r) / 2) + ((l + r) % 2)
if (hasSquare(m))
binary(m, r)
else
binary(l, m - 1)
}
binary(0, a.length)
}
}
import scala.collection.JavaConverters._
// you can write to stdout for debugging purposes, e.g.
// println("this is a debug message")
case class SizeInfo(_max: Int, current: Int) {
def inc = this.copy(current = current + 1)
def max = Math.max(_max, current)
def reset = SizeInfo(max, 0)
}
object Solution {
def solution(a: Array[Int]): Int = {
def hasSquare(side: Int): Boolean = {
val size = a.foldLeft(SizeInfo(0, 0))((size, x) =>
if (x >= side) size.inc else size.reset
)
size.max >= side
}
def binary(l: Int, r: Int): Int =
if (l >= r) l
else {
val m = ((l + r) / 2) + ((l + r) % 2)
if (hasSquare(m))
binary(m, r)
else
binary(l, m - 1)
}
binary(0, a.length)
}
}
The solution obtained perfect score.
Tests with the biggest square surrounded by shorter columns. N <= 10.
Tests with alternating small and big numbers (relatively). N <= 15.
Two monotonic sequences or one monotonic and one constant. N <= 75.
Tests with local maximums and local minimums. N <= 75.