290. Word Pattern
题目:
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
.
Examples:
- pattern =
"abba"
, str ="dog cat cat dog"
should return true. - pattern =
"abba"
, str ="dog cat cat fish"
should return false. - pattern =
"aaaa"
, str ="dog cat cat dog"
should return false. - pattern =
"abba"
, str ="dog dog dog dog"
should return false.
Notes:
You may assume pattern
contains only lowercase letters, and str
contains lowercase letters separated by a single space.
链接: http://leetcode.com/problems/word-pattern/
题解:
跟Isomophic Strings基本一样,使用两个hashmap保持pattern char和string的的一对一关系。 看到Discuss里也有使用一个HashMap的,非常巧妙,对put研究得很深。二刷要使用更好的方法。
Time Complexity- O(n), Space Complexity - O(n)。
public class Solution { private Map<Character, String> patternToStr; private Map<String, Character> strToPattern; public boolean wordPattern(String pattern, String str) { int len = pattern.length(); String[] arrOfStr = str.split(" "); if(len != arrOfStr.length) { return false; } patternToStr = new HashMap<>(); strToPattern = new HashMap<>(); for(int i = 0; i < len; i++) { char c = pattern.charAt(i); if(!patternToStr.containsKey(c) && !strToPattern.containsKey(arrOfStr[i])) { patternToStr.put(c, arrOfStr[i]); strToPattern.put(arrOfStr[i], c); } else if(patternToStr.containsKey(c) && !arrOfStr[i].equals(patternToStr.get(c))) { return false; } else if(strToPattern.containsKey(arrOfStr[i]) && c != strToPattern.get(arrOfStr[i])) { return false; } } return true; } }
二刷:
和一刷方法一样,也和Isomophic Strings一样
Java:
public class Solution { public boolean wordPattern(String pattern, String str) { if (pattern == null || str == null) { return false; } String[] wordArr = str.split(" "); if (pattern.length() != wordArr.length) { return false; } Map<Character, String> pToWord = new HashMap<>(); Map<String, Character> wordToP = new HashMap<>(); for (int i = 0; i < pattern.length(); i++) { char p = pattern.charAt(i); String word = wordArr[i]; if (!pToWord.containsKey(p)) { pToWord.put(p, word); } else if (!pToWord.get(p).equals(word)) { return false; } if (!wordToP.containsKey(word)) { wordToP.put(word, p); } else if (!wordToP.get(word).equals(p)) { return false; } } return true; } }
三刷:
同上。
Java:
public class Solution { public boolean wordPattern(String pattern, String str) { if (pattern == null || str == null) { return false; } String[] words= str.split(" "); if (pattern.length() != words.length) { return false; } Map<Character, String> ps = new HashMap<>(); Map<String, Character> sp = new HashMap<>(); for (int i = 0; i < pattern.length(); i++) { char c = pattern.charAt(i); String word = words[i]; if ((ps.containsKey(c) && !ps.get(c).equals(word)) || (sp.containsKey(word) && sp.get(word) != c)) { return false; } if (!ps.containsKey(c)) { ps.put(c, word); } if (!sp.containsKey(word)) { sp.put(word, c); } } return true; } }
更好的写法来自Stefan Pochmann。
这里比较的是pattern里面的char, 和words里面的word上一次出现的位置是否相同。原理和Isomophic Strings一样。
public class Solution { public boolean wordPattern(String pattern, String str) { if (pattern == null || str == null) { return false; } String[] words= str.split(" "); if (pattern.length() != words.length) { return false; } Map index = new HashMap(); for (Integer i = 0; i < words.length; ++i) { if (index.put(pattern.charAt(i), i) != index.put(words[i], i)) { return false; } } return true; } }
Update:
重写了一下使用两个map
public class Solution { public boolean wordPattern(String pattern, String str) { String[] words = str.split(" "); if (words.length != pattern.length()) return false; Map<Character, String> ps = new HashMap<>(); Map<String, Character> sp = new HashMap<>(); for (int i = 0; i < pattern.length(); i++) { char c = pattern.charAt(i); String word = words[i]; if (!ps.containsKey(c)) ps.put(c, word); else if (!ps.get(c).equals(word)) return false; if (!sp.containsKey(word)) sp.put(word, c); else if (sp.get(word) != c) return false; } return true; } }
利用Map.put,同时遍历pattern和words。 这里map.put()返回的是上一次保存的value,也就是上一次的index i
public class Solution { public boolean wordPattern(String pattern, String str) { String[] words = str.split(" "); if (pattern.length() != words.length) return false; Map map = new HashMap<>(); for (Integer i = 0; i < words.length; i++) { if (map.put(words[i], i) != map.put(pattern.charAt(i), i)) return false; } return true; } }
四刷:
class Solution { public boolean wordPattern(String pattern, String str) { String[] words = str.split(" "); if (pattern.length() != words.length) return false; Map map = new HashMap<>(); for (Integer i = 0; i < words.length; i++) { if (map.put(words[i], i) != map.put(pattern.charAt(i), i)) return false; } return true; } }
Reference:
https://leetcode.com/discuss/62374/8-lines-simple-java
https://leetcode.com/discuss/62876/very-fast-3ms-java-solution-using-hashmap
https://docs.oracle.com/javase/6/docs/api/java/util/Map.html#put%28K,%20V%29