题目:

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

Note: All inputs will be in lower-case.

Hide Tags

Hash Table String 

链接:  http://leetcode.com/problems/anagrams/

题解:

求String数组里所有的异位构词anagram。比如"abcde"和"edcba"算是anagrams,"12345"和"54321"。结果要求返回所有的anagrams在一个ArrayList里,所以我们例子里的结果就是{"abcde", "edcba","12345","54321"}。原理是利用一个HashMap存储String key以及ArrayList<String> value。 Key是排序好的string,比如"abcde"和"edcba"排序后都是"abcde",所以他们都属于同一组anagrams。对于排序后的string,已经在HashMap里存在key的,我们把排序前的原string加入到结果里。当HashMap里存在key而且value.size()为1时,我们要把第一个未排序的string先存入结果。 当HashMap里不存在key,我们要建立这个<key,value>pair。时间复杂度主要在于要对n个string,每个string转换为array之后进行排序,java的Arrays.sort()对于数组的话是使用merge sort,所以时间复杂度是O(n * mlogm),m是每个string的平均长度。空间复杂度的话我们使用了HashMap,临时数组可以不考虑,所以主要是O(n * m)。

Time Complexity - O(n * mlogm),Space Complexity - O(n * m),where m is average length of elements in strs。

public class Solution {
public ArrayList<String> anagrams(String[] strs) {
ArrayList<String> result = new ArrayList<String>();
if(strs == null || strs.length == 0)
return result;
HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>(); for(int i = 0; i < strs.length; i++){
char[] arr = strs[i].toCharArray();
Arrays.sort(arr);
String sortedStr = String.valueOf(arr);
if(map.containsKey(sortedStr)){
if(map.get(sortedStr).size() == 1)
result.add(map.get(sortedStr).get(0));
map.get(sortedStr).add(strs[i]);
result.add(strs[i]);
} else {
ArrayList<String> list = new ArrayList<String>();
list.add(strs[i]);
map.put(sortedStr, list);
}
} return result;
}
}

更新:  Group anagrams

public class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> res = new ArrayList<>();
if(strs == null || strs.length == 0)
return res;
HashMap<String, ArrayList<String>> map = new HashMap<>();
Arrays.sort(strs); for(String str : strs) {
char[] arr = str.toCharArray();
Arrays.sort(arr);
String sortedStr = new String(arr);
if(!map.containsKey(sortedStr)) {
ArrayList<String> list = new ArrayList<>();
list.add(str);
map.put(sortedStr, list);
} else {
map.get(sortedStr).add(str);
}
} for(String str : map.keySet())
res.add(map.get(str)); return res;
}
}

二刷:

现在这道题已经改名叫Group Anagrams了,还加了例子。好人性化的感觉。主要思路还是和一刷一样,对每一个Strs里面的字符串,先生成排序后的新字符串key,然后根据key保存到hashmap里。最后遍历hashmap把结果放在List里。

看了discuss从wz366看到可以直接把map的values转化为结果 -  return new ArrayList<List<String>>(map.values());

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:

  1. For the return value, each inner list's elements must follow the lexicographic order.
  2. All inputs will be in lower-case.

Java:

Time Complexity - O(n * mlogm) , Space Complexity - O(m * n),  m为字符串的平均长度

public class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> res = new ArrayList<>();
if (strs == null || strs.length == 0) {
return res;
}
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
char[] arr = s.toCharArray();
Arrays.sort(arr);
String key = new String(arr);
if (map.containsKey(key)) {
map.get(key).add(s);
} else {
List<String> tmp = new ArrayList<>();
tmp.add(s);
map.put(key, tmp);
}
} List<String> anagrams = new ArrayList<>();
for (String str : map.keySet()) {
anagrams = map.get(str);
Collections.sort(anagrams);
res.add(anagrams);
}
return res;
}
}

或者

public class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> res = new ArrayList<>();
if (strs == null || strs.length == 0) {
return res;
}
Arrays.sort(strs);
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
char[] arr = s.toCharArray();
Arrays.sort(arr);
String key = new String(arr);
if (map.containsKey(key)) {
map.get(key).add(s);
} else {
List<String> tmp = new ArrayList<>();
tmp.add(s);
map.put(key, tmp);
}
}
return new ArrayList<List<String>>(map.values());
}
}

三刷:

方法和前两刷一样。这里先对strs数组进行排序,最后可以一次性返回new ArrayList<List<String>>(map.values);

这样写速度并不快。我们也可以先不排序,计算完hashmap以后, 在遍历hashMap将其每个key对应的values加入到res的时候进行排序。这样的话速度可以增快不少。也就是说跟二刷的第一段代码差不多。

Java:

public class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> res = new ArrayList<>();
if (strs == null) return res;
Arrays.sort(strs);
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
char[] sArr = s.toCharArray();
Arrays.sort(sArr);
String key = String.valueOf(sArr);
if (!map.containsKey(key)) map.put(key, new ArrayList<String>());
map.get(key).add(s);
}
return new ArrayList<>(map.values());
}
}

Reference:

https://leetcode.com/discuss/58561/share-my-short-java-solution

https://leetcode.com/discuss/51190/1-line-ruby-python-for-updated-problem

49. Anagrams的更多相关文章

  1. [Leetcode][Python]49: Anagrams

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 49: Anagramshttps://leetcode.com/proble ...

  2. Leetcode#49 Anagrams

    原题地址 Anagram:变位词.两个单词是变位词关系的条件是:组成单词的字符相同,只是顺序不同 第一次看这道题看了半天没明白要干嘛,丫就不能给个样例输入输出么..后来还是看网上其他人的总结知道是怎么 ...

  3. 【LeetCode】49. Anagrams (2 solutions)

    Anagrams Given an array of strings, return all groups of strings that are anagrams. Note: All inputs ...

  4. LeetCode All in One 题目讲解汇总(持续更新中...)

    终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...

  5. LeetCode 刷题顺序表

    Id Question Difficulty Frequency Data Structures Algorithms 1 Two Sum 2 5 array + set sort + two poi ...

  6. LeetCode Question Difficulty Distribution

    参考链接:https://docs.google.com/spreadsheet/pub?key=0Aqt--%20wSNYfuxdGxQWVFsOGdVVWxQRlNUVXZTdEpOeEE& ...

  7. leetcode难度及面试频率

    转载自:LeetCode Question Difficulty Distribution                 1 Two Sum 2 5 array sort           set ...

  8. Leetcode难度表及解题汇总

    Leetcode难度表及解题汇总 参考网上一份题目难度表,以及本人的解题. Id Question Difficulty Frequency Data Structures Algorithms Bl ...

  9. leetcode刷题指南

    转载自:http://blog.csdn.net/lnho2015/article/details/50962989 以下是我个人做题过程中的一些体会: 1. LeetCode的题库越来越大,截止到目 ...

随机推荐

  1. JS面向对象编程创建类的方式

    js创建类的方式有几种,大致如下: 1,构造函数方式: function Car(parameters) { this.name = "objectboy"; } var cat1 ...

  2. WPF中ListBox的项ListBoxItem被选中的时候Background变化

    使用WPF 中ListBox,点击ListBoxItem的时候,自定义它的背景色,曾经在网上找了一些方法, 不是很理想,后来在StackOverflow上找到了,贴出代码和效果图: 效果图:

  3. centos 6.4 apache开启gzip方法

    系统概况,主机CentOS6.4  Apache2.4 php5.3.6 mysql5.5 开始:首先得确认apache是否已经加载了mod_deflate模块 1.httpd -M 在结果中查看是否 ...

  4. C++中的冒泡排序,选择排序,插入排序

    最简单的插入排序:思想,两两之间比较,时间复杂度o(n^2) void bubblesort(vector<int>&vec, int n) { if (&vec==NUL ...

  5. UI控件tag属性和魔法数字的处理

    说明:tag属性有很大的用处,它就好像每个UI控件的id,当多个按钮指向同一个监听方法时,可以给方法带参数UIButton,然后根据不同的tag值 来判断执行哪个按钮的监听事件: - (IBActio ...

  6. sql行转列和列转行(转)

    行列互转,是一个经常遇到的需求.实现的方法,有case when方式和2005之后的内置pivot和unpivot方法来实现. 在读了技术内幕那一节后,虽说这些解决方案早就用过了,却没有系统性的认识和 ...

  7. struts2传map到前台出现的问题

    后台打印出的错: 2016-08-16 13:42:52.652 WARN  org.apache.struts2.json.JSONWriter     - JavaScript doesn't s ...

  8. For和While在C和MATLAB中的区别——MATLAB的大坑

    For和while是常见的循环关键字,在许多语言中都是通用的.但是想必不是所有人,都被其中的区别困扰过,尤其是MATLAB“程序员”. x=[,,,,,,]; i=; while i<=leng ...

  9. fork 函数 和vfork 函数的区别

    问题描述:         fork 函数 和vfork 函数的区别 问题解决: fork函数使用: 注:         以上printf 属于标准IO库带缓冲,如果标准输出链接到终端设备,则它是行 ...

  10. NYOJ-733 万圣节派对 AC 分类: NYOJ 2014-01-02 00:41 303人阅读 评论(0) 收藏

    #include <stdio.h> #include <math.h> int main() { int t, a, b, i, j, n; scanf("%d&q ...