Home > Back-end >  Kotlin set Array as key for a HashMap
Kotlin set Array as key for a HashMap

Time:11-04

I'm doing a bit of Leetcode, and I'm facing this issue: Group Anagrams, I have a Python background and I can do the following:

res = defaultdic(list)

count = [0] * 26

res[tuple(count)].append(s)

as we can see we can set the tupled array as the key for the dictionary, I want to do the same thing in Kotlin, however, when creating this in Kotlin, I get a different object every time when adding this logic in a for loop.

fun groupAnagrams(strs: Array<String>): List<List<String>> {
    val hashMap = hashMapOf<IntArray, ArrayList<String>>()

    for (word in strs) {
        val array = IntArray(26) { 0 }

        for (char in word) {
            val charInt = char - 'a'

            array[charInt]  = 1
        }

        if (hashMap.containsKey(array)) {
            hashMap[array]!!.add(word)
        } else {
            hashMap[array] = ArrayList<String>().apply { add(word) }
        }
    }

    return hashMap.values.toList()
}

Is this something can be done in Kotlin?

CodePudding user response:

Equality for IntArray is checked based on its reference. You can use a List here in place of IntArray. Two Lists are equal if they contain the same elements.

Modified code will be like this:

fun groupAnagrams(strs: Array<String>): List<List<String>> {
    val hashMap = hashMapOf<List<Int>, ArrayList<String>>()

    for (word in strs) {
        val array = List(26) { 0 }.toMutableList()

        for (char in word) {
            val charInt = char - 'a'
            array[charInt]  = 1
        }

        if (hashMap.containsKey(array)) {
            hashMap[array]!!.add(word)
        } else {
            hashMap[array] = ArrayList<String>().apply { add(word) }
        }
    }

    return hashMap.values.toList()
}

CodePudding user response:

Avoiding the problem you run into (equality of arrays) by using String keys:

fun groupAnagramsWithHashing(strs: Array<String>): List<List<String>> {
    val map = hashMapOf<String, MutableList<String>>()

    MessageDigest.getInstance("SHA-1").also { sha ->
        for (word in strs) {
            word.toByteArray().sorted().forEach { sha.update(it) }

            val key = sha.digest().joinToString()
            map.computeIfAbsent(key) { mutableListOf() }.add(word)
        }
    }
    return map.values.toList()
}

fun main() {
    val input = arrayOf("eat", "tea", "tan", "ate", "nat", "bat")
    groupAnagramsWithHashing(input).also { println(it) }
    // [[eat, tea, ate], [bat], [tan, nat]]
}

  • Related