Anagrams
来源:互联网 发布:铜板街软件 编辑:程序博客网 时间:2024/06/09 17:39
Given an array of strings, return all groups of strings that are anagrams.
Note: All inputs will be in lower-case.
Given an array of strings, return all groups of strings that are anagrams.
Note: All inputs will be in lower-case.
For example:
Input: ["tea","and","ate","eat","den"]
Output: ["tea","ate","eat"]
Interface: vector<string>anagrams(vector<string>&strs);
A:
首先简单介绍一下Anagram(回文构词法)。Anagrams是指由颠倒字母顺序组成的单词,比如“dormitory”颠倒字母顺序会变成“dirty room”,“tea”会变成“eat”。
回文构词法有一个特点:单词里的字母的种类和数目没有改变,只是改变了字母的排列顺序。
看了别人这些方法 无论怎么做,都是为了构建hashmap 的key
假设有n个string,string 最长长度为k
如果用按照字母排序,时间复杂度o(nklogk)
另外两种方法,o(nk)
这道题目除了思路,还要注意对于iterator, collection, map 等 他们的相关方法使用
public class Solution { public List<String> anagrams(String[] strs) { if (strs == null) { return null; } List<String> result = new ArrayList<String>(); HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>(); for (int i = 0; i < strs.length; i++) { if(!hm.containsKey(sortLetter(strs[i]))) { hm.put(sortLetter(strs[i]), new ArrayList<String>()); } hm.get(sortLetter(strs[i])).add(strs[i]); } // hm.values() 返回的是 a collection of the values in this map // 对于collection 结构的数据,都有iterator() 方法 Iterator iter = hm.values().iterator(); while(iter.hasNext()) { ArrayList<String> item = (ArrayList<String>)iter.next(); if(item.size()>1) { result.addAll(item); } } /* hm.values() 返回的是实现了collection 的一种数据类型叫 Values, 不可以被转化为arraylist ArrayList<ArrayList<String>> aa = (ArrayList<ArrayList<String>>)hm.values(); for (int i = 0; i < aa.size(); i++) { if (aa.get(i).size() > 1) { result.addAll(aa.get(i)); } } */ return result; } String sortLetter(String s) { //不要忘记考虑空字符串 if (s == null || s.length() == 0) { return s; } char[] charArr = s.toCharArray(); Arrays.sort(charArr); String str = new String(charArr);//用到String 的构造函数 return str; }}
网上看到另外一人解法 http://huntfor.iteye.com/blog/2077967:
public List<String> anagrams(String[] strs) { List<String> result = new ArrayList<String>(); Map<String,List<String>> map = new HashMap<String,List<String>>(); if(strs == null || strs.length == 1){ return result; } for(String s : strs){ String seq = getSequence(s); if(map.containsKey(seq)){ map.get(seq).add(s); }else{ List<String> list = new ArrayList<String>(); list.add(s); map.put(seq, list); } } for(Map.Entry<String, List<String>> entry : map.entrySet()){ if(entry.getValue().size() > 1){ for(String s : entry.getValue()){ result.add(s); } } } return result; } private String getSequence(String s){ if("".equals(s)){ return ""; } int[] hash = new int[256]; StringBuilder sb = new StringBuilder(); for(int i = 0; i < s.length(); i++){ hash[s.charAt(i)]++; } for(int i = 97; i < 123; i++){ if(hash[i] != 0){ sb.append((char)i).append(hash[i]); } } return sb.toString(); }
第二次写出错的地方:
while (iter.hasNext()) { ArrayList<String> items = (ArrayList<String>)iter.next(); //cannot addAll(iter.next()) directely //res.addAll(iter.next()); //test case:[""], the output should be [ ] if (items.size() > 1) { res.addAll(items); } }
/** * Copyright: NineChapter * - Algorithm Course, Mock Interview, Interview Questions * - More details on: http://www.ninechapter.com/ */public class Solution { private int getHash(int[] count) { int hash = 0; int a = 378551; int b = 63689; for (int num : count) { hash = hash * a + num; a = a * b; } return hash; } public ArrayList<String> anagrams(String[] strs) { ArrayList<String> result = new ArrayList<String>(); HashMap<Integer, ArrayList<String>> map = new HashMap<Integer, ArrayList<String>>(); for (String str : strs) { int[] count = new int[26]; for (int i = 0; i < str.length(); i++) { count[str.charAt(i) - 'a']++; } int hash = getHash(count); if (!map.containsKey(hash)) { map.put(hash, new ArrayList<String>()); } map.get(hash).add(str); } for (ArrayList<String> tmp : map.values()) { if (tmp.size() > 1) { result.addAll(tmp); } } return result; }}
方法挺简单就是建立一个int数组来记录一个字符在一个string里面出现的次数 然后对比int[]数组是否相等就好。 不过这里有几个注意点和小技巧。 int数组可以只设为26而不是256, 然后数组这样的Object类型没法直接用来做key首先要写一个函数把它的hash值转换为基本数据类型。 然后就是要存arraylist作为value,因为如果直接把string用来做value最后会少加一次anagrams进rs。用arraylist存只要size大于1 就可以addall.public class Solution { public List<String> anagrams(String[] strs) { List<String> rs = new ArrayList<String>(); if (strs.length < 2) { return rs; } HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>(); for (String i : strs) { int len = i.length(); int[] temp = new int[26]; for (int j = 0; j < len; j++) { temp[i.charAt(j) - 'a']++; } String t = getString(temp); if (!hm.containsKey(t)) { hm.put(t, new ArrayList<String>()); } hm.get(t).add(i); } for (ArrayList<String> i : hm.values()) { if (i.size() > 1) { rs.addAll(i); } } return rs; } private String getString(int[] a) { StringBuilder sb = new StringBuilder(); for (int i : a) { sb.append(i); } return sb.toString(); }}
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- Anagrams
- anagrams
- Anagrams
- Anagrams
- Anagrams
- OC中动态创建可变数组的问题.有一个数组,数组中有13个元素,先将该数组进行分组,每3个元素为一组,分为若干组,最后用一个数组统一管理这些分组.(要动态创建数组).两种方法
- 监控常用TCODE
- 字典基础总结,初学者必备
- matlab学习------------颜色选择对话框uisetcolor
- linux编程--管道编程
- Anagrams
- HDU 4951 Multiplication table 数论
- 第2章:R的数据可视化,各种图表,常用统计量计算
- 将两个排好序的数组,合并到另外一个数组中,并且合并之后的数组也是有序的。
- jQuery 增加 删除 修改select option .
- 给定一个二进制数,要求循环移位,在原二进制数中操作(C语言)
- 读写外挂
- Windows线程同步
- 指针