Leetcode刷题总结
文章主要记录了笔者刷leetcode时,遇到的新的解题技巧和思路,用于个人的学习总结和参考。
1. 映射关系建立
笔者在解题时,遇到一些需要建立映射关系的题。第一考虑就是map,在使用map的时候,会造成额外空间的浪费,但是map建立哈希,寻址快,所以用起来较顺手。今天get到一个采用位运算方式建立映射的方法,来源于Leetcode-1684题,统一一致字符串的数目。
题目描述
最开始的分析
笔者拿到题的第一考虑,是将allowed的每个字符存到map,建立hash映射
match = map(uint8)bool, 字符c存在, 则match[c] = true
之后遍历words数组,判断每一个word是否是一致字符串
判断方式,对每一个word,循环拿到每一个字符c if !match[c] 字符不存在,则不是一致字符串
位运算建立映射
这个思路来源于该题go语言提交速度最快代码
直接上代码
func countConsistentStrings(allowed string, words []string) int {
// 记录返回结果,一致字符串的数量
ret := 0
almatch := getMatch(allowed)
for _, word := range words {
wordMatch := getMatch(word)
// 见代码分析
if almatch & wordMatch == wordMatch {
ret++
}
}
return ret
}
// 建立映射的方式
func getMatch(str string) int {
match := 0
for i := range str {
// 见代码分析
match |= 1 << (str[i] - 'a')
}
return match
}
代码分析
- getMatch用于转化映射关系,他的原理是这样的
比如有字符串abcefg
那么他就能转化成二进制 1110111
其实就是将字符串的a变成低1位,b变成低2位
然后与match做或运算,能够保证每个字符都成功映射到match上面- 将每一个word也通过getMatch去转化一个映射
- 判断word是否是一致性字符串的方式:将word的映射和allowed的映射相与,再和他的映射比较。
如:
allowed = abcefg, alMatch = 1110111
- word1 = abef, word1Match = 110011, alMatch & word1Match = 110011, = word1Match, 所以word1 是一致性字符串
- word2 = adef, word2Match = 111001, alMatch & word2Match = 110001 != word2Match, 所以word2不是一致性字符串