Skip to main content

O1Data Structure

Construct a DS with search, remove and add operations of O(1) in worst case The elements are drawn from the finite set and initialization can take place at O(n)

package algorithmdesignmanualbook.datastructures

import algorithmdesignmanualbook.withPrint
import utils.PrintUtils
import utils.assertIterableSameInAnyOrder
import java.util.*

/**
* Construct a DS with search, remove and add operations of O(1) in worst case
* The elements are drawn from the finite set and initialization can take place at O(n)
*/
class O1DataStructure {
/**
* Value to [array] index mapping
*/
private val map = mutableMapOf<Int, Int>()
private val array = mutableListOf<Int>()

fun add(value: Int) {
if (map.containsKey(value)) {
return
}
// Update both ds
array.add(value)
map[value] = array.lastIndex
}

fun remove(value: Int) {
if (!map.containsKey(value)) {
return
}
// Swap with the last element
swap(map[value]!!, array.size - 1)
// remove from map
map.remove(value)
// Remove the last element
array.removeAt(array.size - 1)
}

fun getRandomOrNull(): Int? {
if (array.isEmpty()) {
return null
}
val rand = Random()
return array.elementAt(rand.nextInt(array.size))
}

private fun swap(srcIndex: Int, destIndex: Int) {
val srcValue = array[srcIndex]
val destValue = array[destIndex]
// Update array
val temp = array[srcIndex]
array[srcIndex] = destValue
array[destIndex] = temp

// Update map
map[srcValue] = destIndex
map[destValue] = srcIndex
}

fun print() {
PrintUtils.println(array)
}

fun asList(): List<Int> {
return array
}
}

fun main() {
val ds = O1DataStructure()
ds.add(1)
ds.add(2)
ds.add(3)
ds.add(4)
assertIterableSameInAnyOrder(expected = listOf(1, 2, 3, 4), actual = ds.asList())
ds.print()

withPrint("Random elements") {
println(ds.getRandomOrNull())
println(ds.getRandomOrNull())
println(ds.getRandomOrNull())
}

ds.remove(1)
ds.remove(2)
ds.print()
assertIterableSameInAnyOrder(expected = listOf(3, 4), actual = ds.asList())
ds.remove(3)
ds.remove(4)
assertIterableSameInAnyOrder(expected = listOf(), actual = ds.asList())
ds.print()
}


Updated on 2021-02-08