题目
Given an array of strings, group anagrams together.
For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"],
Return:
[
["ate", "eat","tea"],
["nat","tan"],
["bat"]
]
Note:
For the return value, each inner list's elements must follow the lexicographic order.
All inputs will be in lower-case.
思路一
此思路比较传统,就是从字符串数组从头开始遍历分别找到与第i个字符串含相同字符的所有字符串,并组合为一个List加入到List< List>中;最后对每个List的字符串按字典进行排序。时间复杂度为O(n^2)
package com.wrh.leetcode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Solution_1 {
public String my_sort(String str){
char[] s1 = str.toCharArray();
//System.out.println(s1);
for(int i=0;i<s1.length;i++){
for(int j=0;j<i;j++){
if(s1[i]<s1[j]){
char temp = s1[i];
s1[i] = s1[j];
s1[j] = temp;
}
}
}
return String.valueOf(s1);
}
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> list=new ArrayList<List<String>>();
if(strs==null){
return list;
}
for(int i=0;i<strs.length;i++){
List<String > list1=new ArrayList<String>();
if(strs[i]!=""){
list1.add(strs[i]);
}
else{
continue;
}
String tempStr1=my_sort(strs[i]);
for(int j=i+1;j<strs.length;j++){
if(tempStr1.equals(my_sort(strs[j]))){
list1.add(strs[j]);
strs[j]="";
}
}
list.add(list1);
}
//将list中每个子list中的元素进行按字典排序。
for(List tempList:list){
Collections.sort(tempList);
}
return list;
}
public static void main(String []args){
Solution_1 s=new Solution_1();
String[] strs=new String[]{"eat","ate","tea","nat","tan","ban"};
List<List<String>> l=s.groupAnagrams(strs);
for(List list:l){
System.out.println(list.toString());
}
}
}
代码报超时错误
因此,只能寻找更好的方法。
改进一
将自己写的my_sort换成了系统自带的。但是还是报超时错误。因此还是得继续改进,将时间复杂度O(n^2)降低为n的线性。
public class Solution {
public String my_sort(String str){
char[] s1 = str.toCharArray();
Arrays.sort(s1);
return String.valueOf(s1);
}
public List<List<String>> groupAnagrams(String[] strs) {
Arrays.sort(strs);
List<List<String>> list=new ArrayList<List<String>>();
if(strs==null){
return list;
}
for(int i=0;i<strs.length;i++){
List<String > list1=new ArrayList<String>();
if(strs[i]!=""){
list1.add(strs[i]);
}
else{
continue;
}
String tempStr1=my_sort(strs[i]);
for(int j=i+1;j<strs.length;j++){
if(tempStr1.equals(my_sort(strs[j]))){
list1.add(strs[j]);
strs[j]="";
}
}
list.add(list1);
}
return list;
}
}
改进二
思路还是原来的思路,只是这里借用了Map,因此,这样就将O(n^2)降为了O(n);
实现代码如下
public List<List<String>> groupAnagrams(String[] strs) {
if(strs==null){
return null;
}
//借用Map来做
Arrays.sort(strs);//对字符数组进行排序
int len=strs.length;
Map<String,List<String>> map=new HashMap<String ,List<String>>();
for(int i=0;i<len;i++){
String curString=strs[i];
//先将此字符串转化为char数组,然后将其排序。这样就导致所有含有相同字符的字符串都是一个key。
char ch[]=curString.toCharArray();
Arrays.sort(ch);
String key=String.valueOf(ch);
List<String> list=map.getOrDefault(key, new ArrayList<String>());//没有就返回默认的List
list.add(curString);
map.put(key, list);
}
return new ArrayList<>(map.values());
}