Given a pattern and a string str, find if str follows the same pattern.
Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.
Example:
Input: pattern = "abba", str = "dog cat cat dog"
Output: true
Input:pattern = "abba", str = "dog cat cat fish"
Output: false
Input: pattern = "aaaa", str = "dog cat cat dog"
Output: false
Input: pattern = "abba", str = "dog dog dog dog"
Output: false
- 一个字母对应一个单词,看看造句的小朋友语文过不过关。
class Solution:
def wordPattern(self, pattern, str):
"""
:type pattern: str
:type str: str
:rtype: bool
"""
a=str.split(' ')
b=pattern
if len(b)!=len(a): # flag 1
return False
c=[]
dic={}
for i in range(len(b)):
if b[i] not in dic:
dic[b[i]]=a[i]
c.append(dic[b[i]])
if len(set(dic.values()))!=len(set(b)): # flag 2
return False
return a==c
- 对于一一对应的映射关系,选用字典作为存储结构最合适不过了。
- 主体思路是:
- 将str直接以空格为界,分割成单词的list。
- 读取每一个pattern的字母,同时读取相应位次的单词。
- 如果字母不在字典里,就把字母:单词对存进字典。
- 直接用字典里的对照关系来构建新的list:
- 这样子,list中的所有单词就是字母:单词对在遍历时第一次出现的模样。
- 换而言之,就是构建出了一个绝对正确的(异字母同词除外)的list。
- 最后,比较两个list是否相同即可。
- 更省空间的做法:不是构建新list,而是遍历的时候直接比较当前单词与字典的值是否相等。
这里面有几个额外的flag:
- flag 1: 干掉连数数都不会的弱智小朋友。
- flag 2: 干掉异字母同单词的杠精小朋友(Example 4):
- 对比字母种类(set是个好东西)以及字典的值(set是个好东西)是否相同即可。
可是,python里面有个摸鱼函数,能够让这个问题变得更摸:
>>> for i in zip('zg101',['皮鞭','蜡烛','口塞','手铐','紧身衣']):
print(i)
('z', '皮鞭')
('g', '蜡烛')
('1', '口塞')
('0', '手铐')
('1', '紧身衣')
- 捆绑切片一步到位,真乃摸鱼界的豪杰。
- 用上zip大魔王之后,代码就变成了这样:
class Solution:
def wordPattern(self, pattern, str):
"""
:type pattern: str
:type str: str
:rtype: bool
"""
a=str.split(' ') # split()的默认值也是空格,所以这里不填参数也是可以的。
z=zip(a,pattern)
return (len(set(a))==len(set(pattern))==len(set(z)) and len(a)==len(pattern))
- 如果我有n种字母,也有n种单词,还有n种绑定模式,此外,单词和字母的总数也是一致的,那么确实是对的。
- 这时,有些邪恶的念头浮现了出来:
return (len(set(str.split()))==len(set(pattern))==len(set(zip(str.split(),pattern))) and len(str.split())==len(pattern))
- 这就是猥琐老秃头们写one-line solution的其中一个小技巧。