本次刷题日记的第 62 篇,力扣题为:890. 查找和替换模式,中等
一、题目描述:
查找和替换模式,一看又是一个字符串处理的题,看看需要我们如何去匹配
二、这道题考察了什么思想?你的思路是什么?
查找和替换字符串,看看题目标记了哪些重点信息:
- 题目中给出了一个字符串列表,里面的字符串都是字母,顺序不一
- 题目还给出了一个匹配模式,pattern,要我们确认上述列表中有哪些字符串是匹配这个模式的
分析
匹配模式,这么一看是需要我们明确模式中和字符串中的字母做一个一一对应的关系,例如咱们在学习语文的时候,让我们写一些关于 ABB 的词语,例如白茫茫,笑嘻嘻 等这种 ABB 的词语
大脑是很轻易的能够看出来的,但是如何让电脑也能正确的获取并计算出来呢?
我们就需要一套可行的步骤清晰的算法,来让计算机按部就班的来执行,最终得到咱们期望的结果
上述说到咱们需要将匹配模式和需要匹配字符串做一个映射关系,那么我们可以映射的方式有很多,例如,我们可以使用 golang 中的 map 来做映射, map 的 key 是具体需要匹配的单词对应的字母,value 是匹配模式的字母
例如 pattern = "abb" ,需要匹配的字符串是 "abc" ,那么就有 map['a'] = 'a' ...
正如这个例子,我们可以来看图
待匹配的单词 | pattern |
a | a |
b | b |
c | b |
我们可以知道有映射关系如:
a -- a
b -- b
c -- b
那么我们单单的通过这一组映射就能够正确的判断出 "abc" 是否符合 "abb" 的模式了吗?
明眼人可以看出来,上述的 key 确实是对应这不同的值,但是其实我们还发现了 不同的 key 居然对应了相同值,这种是不可取的,因此我们需要再做一次反向映射,去掉这种能够 1 个 key 对应多个值,或者是 1 个 值对应多个 key 的情况
pattern | 待匹配的单词 |
a | a |
b | b |
b | c |
a -- a
b -- b
b -- c
这样来看, b 是即 对应 b 又 对应 c ,那么肯定是不成立的,因此,我们可以运用 map 中 key 是唯一的来进行处理,遇到这种情况,无论正向映射还是反向映射,只要有出现 1 个 key 对应 多个值的情况,那么这个待匹配的字符串,就不匹配当前模式
三、编码
根据上述逻辑和分析,我们就可以翻译成如下代码
这里需要注意的是,咱们编码的时候,务必进行正向映射和反向映射,必须是全为 true ,这个待匹配的字符串才是匹配我们期望的模式的
编码如下:
func findAndReplacePattern(words []string, pattern string) []string { res := []string{} for _,w := range words { if match(w, pattern) && match(pattern, w){ res = append(res, w) } } return res } func match(word , pattern string) bool { help := map[rune]byte{} for i,v := range word{ if help[v] == 0 { help[v] = pattern[i] }else if help[v] != pattern[i] { return false }else{} } return true }
结:
咱们这种实现方式比较明确,有点暴力哈,不过确实需要这样的去匹配双映射情况,咱们令外部的循环为 n ,内部 match 函数的循环为 m ,则时间复杂度是 O(nm)
那么空间复杂度是多少呢,我们可以看到咱们引入的空间消耗都是 match 函数中临时开辟的空间,因此咱们的空间复杂度是 O(m)
原题地址:890. 查找和替换模式
今天就到这里,学习所得,若有偏差,还请斧正
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~