Дан произвольный двумерный массив целых чисел (скажем):
0, 1, 1, 0, 0
1, 1, 1, 0, 0
1, 1, 1, 1, 1
1, 1, 1, 1, 1
0, 0, 1, 0, 0
Мне нужен метод для разделения этого массива на самые большие непрерывные "квадраты" каждого значения:
// Should return a map of 2D array chunks keyed to the "start" indices of the chunk.
fun Array<Array<Int>>.chunkBy(): Map<Pair<Int, Int>, Array<Array<Int>>> {
TODO("Not Implemented")
}
val array: Array<Array<Int>> = ...
val oneBlocks: = array.chunkBy(1)
// The chunk starting @ 0,1 should be a 3x3 array of ints
assertEquals(oneBlocks[0 to 1], arrayOf(
intArrayOf(1, 1, 1,),
intArrayOf(1, 1, 1,),
intArrayOf(1, 1, 1,)
)
// No chunks start @ 1,1 so should be null
assertNull(oneBlocks[1, 1])
// 1x1 chunks are acceptable
val zeroBlocks = array.chunkBy(0)
assertEquals(zeroBlocks[0 to 4], arrayOf(intArrayOf(0)))
Для меня это похоже на проблему с рюкзаком , но, поскольку я могу подразделить массив на наименьшее возможное значение элемента, мне также кажется, что его проще реализовать.
Я рассмотрел несколько разных реализаций; тот, который я рассматриваю, включает в себя поиск самого большого блока в сетке и маркировку этих ячеек как посещенных, затем повторение с меньшими и меньшими размерами, пока не будут отмечены только блоки 1x1, но меня интересует, имеет ли эта проблема более общее решение .