您的位置:首页 > 职场人生

LeetCode 049 Anagrams

2014-02-02 08:52 253 查看
题目

原文

Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

译文

输入一组字符串,输出所有重组字相同的字符串。

解答

首先,要理解 anagram 的含义。"abc" 和 ''bca", ''cba"都是anagram, "abc" 和 "abcd" 不是anagram。

之后,当我看到lower-case的时候,一下子理解为" 所有输入都是小写字母",如此一来,直接想到只要借助一个大小26 的字符数组,来做统计,就能够完成题目。

假设有n个字符串,我要统计字符串每个字符出现的次数,所以需要二维数组,行表示第i个字符串,列表示字符。

int n =strs.length;
int[][] count = new int
[26];
for(int i=0;i<n;i++){
String temp = strs[i];
char[] c = temp.toCharArray();
for(int j=0;j<c.length;j++){
count[i][c[j]-'a']++;
}
}

之后只要比较这个数组的哪些行相等即可了。只要有行相等就插入给最后的链表,

boolean[] id  = new boolean
;
ArrayList<String> s = new ArrayList<String>();
for(int i=0;i<n;i++){
//只要出现过重复的就不看了
if(id[i]==true){
continue;
}
int j;
int sign =1;
s.add(strs[i]);
//查看之后的是否和目前这个相同
for(j=i+1;j<n;j++){
boolean identical = true;
for(int k=0;k<25;k++){
if(count[i][k]!=count[j][k]){
identical=false;
break;
}

}
//如果出现的字符都相同,就加入答案
if(identical == true){
s.add(strs[j]);
id[j]=true;
sign=0;
continue;
}
}
//如果没出现过,删除事先加入进去的这个
if(sign==1){
s.remove(0);
}
}


说时迟,纳什快,我这就兴高采烈地submit,结果。。。time exceed,原因是碰到大数据超时。

思考一下用的时间:设有n个字符串,每个字符串n个字符。生成数组O(nm), 之后比较需要O(n^2)的时间。

的确不是很理想。参考了讨论,发觉的确有个我遗漏的方式 HashMap,思路是既然 重组字 最后重组后的字符串都相同,那么就把它作为Map 的key ,然后value类型很关键,如果只是一个字符串,放不下重复的;那么就放一个链表,把所有相同的都串起来。最后输出串的超过2的。

代码如下(论坛上的,我觉得非常简洁):
public class Solution {
public ArrayList<String> anagrams(String[] strs) {
// Start typing your Java solution below
// DO NOT write main() function
ArrayList<String> anagram = new ArrayList<String>();
HashMap<String,ArrayList<String>> list = new
HashMap<String,ArrayList<String>>();
for (String str: strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
if (list.containsKey(key)) {
list.get(key).add(str);
} else {
list.put(key,new ArrayList<String>
(Arrays.asList(str)));
}
}
for (ArrayList<String> test:list.values()) {
if (test.size()>1) {
anagram.addAll(test);
}
}
return anagram;
}
}


时间上来说,对于每个字符,快排O(mlgm),list查找1;最差情况下,都相同,arraylist加入新元素,需要平均n/2的次数,n个字符,总共就是O(n*(mlgm+n/2)),和前面方法一个数量级;但是一般情况,不会如此,基本O(nmlgm),在m远小于n的情况下,第二种方法更加好。

PS 这道题目,要把所有重组字相同的组都给输出,而不是只输出一组。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 面试笔试