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.
Java Solution
public boolean wordPattern(String pattern, String str) { String[] arr = str.split(" "); //prevent out of boundary problem if(arr.length != pattern.length()) return false; HashMap<Character, String> map = new HashMap<Character, String>(); for(int i=0; i<pattern.length(); i++){ char c = pattern.charAt(i); if(map.containsKey(c)){ String value = map.get(c); if(!value.equals(arr[i])){ return false; } }else if (map.containsValue(arr[i])){ return false; } map.put(c, arr[i]); } return true; } |
Python3 equivalent:
def check(pattern, arr):
arr_w=arr.split()
if(len(pattern)!=len(arr_w)):
return False
dictpat={}
for i in range(len(pattern)):
if pattern[i] in dictpat:
if(dictpat[pattern[i]]!=arr_w[i]):
return False
elif(arr_w[i] in dictpat.values()):
return False
dictpat[pattern[i]]=arr_w[i]
return True
Test Case:
pat=”abaabbc”
words=”dog cat dog dog cat cat donkey”
print(check(pat, words))
O(N) solution.. not splitting the str to words
public boolean wordPattern(String pattern, String str) {
int countOfWords = pattern.length();
Map oneToOneMap = new HashMap();
String word = null;
int start = 0;
char ch = ' ';
for(int j = 0; j < str.length(); j++){
if(countOfWords == 0){
return false;
}
if(str.charAt(j) == ' '){
//word
word = str.substring(start, j);
ch = pattern.charAt(pattern.length() - countOfWords);
countOfWords--;
start = j+1;
if(!isValidRelation(oneToOneMap , ch, word)){
return false;
}
}
}
if(start < str.length()){
if(countOfWords == 0){
return false;
}
word = str.substring(start);
ch = pattern.charAt(pattern.length() - countOfWords);
countOfWords--;
if(!isValidRelation(oneToOneMap , ch, word)){
return false;
}
}
return countOfWords == 0;
}
boolean isValidRelation(Map oneToOneMap , char ch, String word){
if(oneToOneMap.containsKey(ch)){
if(!word.equals(oneToOneMap.get(ch))){
return false;
}
}else if(oneToOneMap.containsValue(word)){
return false;
}else{
oneToOneMap.put(ch, word);
}
return true;
}
Not a O(N) solution, to make it a O(N) linear solution we could use a reverse map as well.