Kotlin中能否将IntArray作为HashMap的键实现字母异位词分组?
问题原因
Kotlin 中的IntArray(对应Java原生数组int[])的equals()与hashCode()方法默认基于对象引用地址判断,而非数组内容。哪怕两个IntArray存储的计数完全一致,只要是不同实例,就会被HashMap识别为不同的键,这和Python中不能直接用list作为字典键、需要转成tuple的逻辑是一致的。
实现方案
完全可以实现相同的分组逻辑,推荐以下2种常用方案:
方案1:将计数数组转为List<Int>作为键(最贴近Python的实现逻辑)
Kotlin的List默认基于内容判断相等性,和Python的tuple行为一致,只需要对原有代码做极小修改:
fun groupAnagrams(strs: Array<String>): List<List<String>> { val hashMap = hashMapOf<List<Int>, ArrayList<String>>() for (word in strs) { val array = IntArray(26) { 0 } for (char in word) { val charInt = char - 'a' array[charInt] += 1 } // 把IntArray转成List作为键,基于内容对比相等 val key = array.toList() hashMap.getOrPut(key) { ArrayList() }.add(word) } return hashMap.values.toList() }
方案2:将计数数组转为特征字符串作为键
也可以把计数数组拼接为带分隔符的字符串作为键,性能和方案1差异不大:
fun groupAnagrams(strs: Array<String>): List<List<String>> { val hashMap = hashMapOf<String, ArrayList<String>>() for (word in strs) { val array = IntArray(26) { 0 } for (char in word) { array[char - 'a'] += 1 } // 拼接成类似 "0,1,0,..." 的字符串作为键 val key = array.joinToString(",") hashMap.getOrPut(key) { ArrayList() }.add(word) } return hashMap.values.toList() }
补充说明
如果一定要直接用数组作为键,你可以自定义包装类重写equals()和hashCode()方法,基于数组内容计算哈希值、判断相等,但实现成本高于上述两种方案,常规场景下没有必要使用。
内容的提问来源于stack exchange,提问作者Andrey Solera
相关产品推荐
相关产品推荐

