class Solution {
public List<List<String>> groupStrings(String[] strings) {
List<List<String>> res = new ArrayList<List<String>>();
Map<Integer, List<List<String>>> map = new HashMap<Integer, List<List<String>>>();
// group by len
for (String s : strings) {
int len = s.length();
if (!map.containsKey(len)){
map.put(len, new ArrayList<List<String>>());
List<String> tmpList = new ArrayList<String>();;
tmpList.add(s);
map.get(len).add(tmpList);
} else {
boolean added = false;
for (List<String> list : map.get(len)) {
if (same(list.get(0), s)) {
list.add(s);
added = true;
break;
}
}
if (!added) {
List<String> tmpList = new ArrayList<String>();
tmpList.add(s);
map.get(len).add(tmpList);
}
}
}
// add to result
for (List<List<String>> lists : map.values()) {
for (List<String> list : lists) res.add(list);
}
return res;
}
private boolean same(String s1, String s2) {
int diff = (s2.charAt(0) - s1.charAt(0) + 26) % 26;
for (int i = 1; i < s1.length(); i++) {
int num1 = s1.charAt(i) - 'a';
int num2 = s2.charAt(i) - 'a';
if ( (num1 + diff) % 26 != num2 ) return false;
}
return true;
}
}
ac2: transform every word back to base status
class Solution {
public List<List<String>> groupStrings(String[] strings) {
List<List<String>> res = new ArrayList<List<String>>();
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String s : strings) {
// get base key
String key = "";
int diff = s.charAt(0) - 'a';
for (int i = 0; i < s.length(); i++) {
char c = (char) (s.charAt(i) - diff);
if (c < 'a') c += 26;
key += c;
}
// add to map
if (!map.containsKey(key)) map.put(key, new ArrayList<String>());
map.get(key).add(s);
}
// add to result return
for (List<String> list : map.values()) {
res.add(list);
}
return res;
}
}