思路:全部写在代码注释中。直接上代码:
class Solution {
public List<List<String>> groupStrings(String[] strings) {
//用来存储最后的结果
List<List<String>> res = new ArrayList<>();
//新建一个list类型数组,将strings中的字符串们分门别类,一类归一类地存放进list数组中,每一类都是一个arraylist
ArrayList<String>[] list = new ArrayList[strings.length];
//必须要初始化list[i],否则他们的value都是null,这会导致不可以使用list[i].add()函数。抛出异常NullPointerException
for(int i = 0; i < list.length; i++){
list[i] = new ArrayList<>();
}
//新建一个map,用来存储strings中的string,之后遍历strings的时候要用来判断当前string是否已写入list
Map<String,Boolean> mappings = new HashMap<>();
//遍历strings,两两比较,看是否属于同一个sequence
for(int i = 0; i < strings.length ; i++){
//判断是否已经在list中,如是,跳过当前循环
if(mappings.containsKey(strings[i])){continue;}
list[i].add(strings[i]);
mappings.put(strings[i],true);
for(int j = i + 1; j < strings.length; j++){
if(strings[i].length() != strings[j].length()){
continue;
}else{
if(isSameSequence(strings[i],strings[j])){
list[i].add(strings[j]);
mappings.put(strings[j],true);
}
}
}
}
//将数组list中的每一个长度不为0的arraylist输出到res中,res即为最后的返回结果
for(int i = 0; i < list.length; i++){
if(list[i].size() != 0){
res.add(list[i]);
}
}
return res;
}
//判断两个字符串是否属于同一个sequence
private boolean isSameSequence(String s1, String s2){
int num = ((s1.charAt(0) - s2.charAt(0)) - 26) % 26;
for(int i = 0; i < s1.length(); i++){
if((((s1.charAt(i) - s2.charAt(i)) - 26) % 26) != num){
return false;
}
}
return true;
}
}
总结:
- 要熟练运用字符的ascii
- 如何创建一个元素类型是ArrayList的数组:ArrayList a[] = new ArrayList[len];
- List add()返回java.lang.NullPointerException。说明list的值是null,需要初始化。list = new ArrayList<>();
- 判断ArrayList数组是否为空: list[i].size() == 0