题目描述#

给定一个规律字符串 pattern 和一个字符串 s,判断它们是否满足同一套映射关系。

这里的关键是双向一一对应:

  • pattern 中的每个字符都只能映射到一个唯一单词
  • s 中的每个单词也只能映射到一个唯一字符
  • 不能出现两个字符映射到同一个单词,也不能出现两个单词映射到同一个字符

思路#

先用 strings.Split 按空格拆出所有单词。如果单词数量和 pattern 的长度不一致,那么肯定不匹配,可以直接返回 false

接下来需要同时维护两张哈希表:

  • patt2s:记录某个模式字符当前映射到哪个单词
  • s2patt:记录某个单词当前映射到哪个模式字符

遍历 pattern 的每一个位置时,取出当前字符 p 和对应单词 word

如果 patt2s 里已经有这个字符,就检查它之前映射的单词是不是当前单词;如果不是,说明同一个字符对应了不同单词,直接返回 false。反过来,再检查 s2patt 里这个单词之前是不是已经映射给了别的字符;如果是,也要返回 false

只有两个方向都不冲突,才能说明当前这一对映射合法。整轮遍历结束后还没有冲突,就说明整个字符串满足题意。

这个写法的重点不在于“字符能不能找到单词”,而在于“一一对应”必须双向同时成立,所以两张哈希表都不能省。

代码#

import "strings"

func wordPattern(pattern string, s string) bool {
	words := strings.Split(s, " ")
	if len(words) != len(pattern) {
		return false
	}
	patt2s := make(map[byte]string)
	s2patt := make(map[string]byte)

	for i := 0; i < len(pattern); i++ {
		word := words[i]
		p := pattern[i]
		if v, ok := patt2s[p]; ok {
			if v != word {
				return false
			}
		} else {
			patt2s[p] = word
		}

		if v, ok := s2patt[word]; ok {
			if v != p {
				return false
			}
		} else {
			s2patt[word] = p
		}
	}
	return true
}
本站总访问量  ·  访客数
你的IP 获取中…