[LintCode] Anagrams

本文介绍了一种高效算法,用于从字符串数组中找出所有的异位词组。通过使用哈希映射并排序每个字符串,该算法能在O(n*k*logk)的时间复杂度内解决问题,其中n为字符串数量,k为字符串平均长度。

Given an array of strings, return all groups of strings that are anagrams.  All inputs will be in lower case.

What is Anagram?
- Two strings are anagram if they can be the same after change the order of characters.

Example

Given ["lint", "intl", "inlt", "code"], return ["lint", "inlt", "intl"].

Given ["ab", "ba", "cd", "dc", "e"], return ["ab", "ba", "cd", "dc"].

 

Solution 1. Brute Force

The most straightforward solution is to from left to right, fix a string, and compare it with all the remaining

not-added strings on its right side. (By checking only the strings on its right side, we avoid the possiblity of

adding duplicate strings.)If found any anagrams, add this string and its anagrams to the result list and mark

them as added. Repeat this until we've checked all strings.

 

This solution is not efficient, with a runtime of O(n^2 * k), where n is the number of strings, k is the average 

length of each string.

 

Solution 2. 

For a string and all its possible anagram strings, we have k! different permutations. (assuming only distinct characters for simplicity)

For a group of anagrams, if we fix one order, say ascending by sorting, we will only have to scan through the input list of strings 

once.

 

1. Create a hash map. Its keys are the ascending order of a string, its values are a list of all the anagrams of its keys.

2. For each string, sort it, use this sorted string as key and add the unsorted string to the list of anagrams strings.

3. Scan through the hash map and add all lists that have more than 1 string to the final result.

 

This solution has a O(n * k * log k) runtime and O(n) space usage.

 

 1 public class Solution {
 2     public List<String> anagrams(String[] strs) {
 3         List<String> result = new ArrayList<String>();
 4         if(strs == null || strs.length == 0){
 5             return result;
 6         }
 7         HashMap<String, ArrayList<String>> hashmap = new HashMap<String, ArrayList<String>>();
 8         for(String s : strs){
 9             char[] chars = s.toCharArray();
10             Arrays.sort(chars);
11             String sortedStr = String.valueOf(chars);
12             if(hashmap.containsKey(sortedStr)){
13                 hashmap.get(sortedStr).add(s);
14             }
15             else{
16                 ArrayList<String> list = new ArrayList<String>();
17                 list.add(s);
18                 hashmap.put(sortedStr, list);
19             }
20         }
21         for(String s : hashmap.keySet()){
22             ArrayList<String> list = hashmap.get(s);
23             if(list.size() > 1){
24                 result.addAll(list);    
25             }
26         }
27         return result;
28     }
29 }

 

 

Related Problems

Strings Homomorphism

Substring Anagrams

Two Strings Are Anagrams

转载于:https://www.cnblogs.com/lz87/p/6943162.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值