zoukankan      html  css  js  c++  java
  • 49. Anagrams

    题目:

    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

  • 相关阅读:
    js简单的双向绑定
    angular的$scope
    angular一些冷门的用法
    堆栈
    angular一些有启发的博客
    160830、如何运用最新的技术提升网页速度和性能
    160829、Java加解密与数字签名
    160826、浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘
    160825、互联网架构,如何进行容量设计?
    160824、ionic添加地图站点
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4436355.html
Copyright © 2011-2022 走看看