zoukankan      html  css  js  c++  java
  • [LeetCode] 49. Group Anagrams

    Given an array of strings strs, group the anagrams together. You can return the answer in any order.

    An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

    Example 1:

    Input: strs = ["eat","tea","tan","ate","nat","bat"]
    Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
    

    Example 2:

    Input: strs = [""]
    Output: [[""]]
    

    Example 3:

    Input: strs = ["a"]
    Output: [["a"]] 

    Constraints:

    • 1 <= strs.length <= 104
    • 0 <= strs[i].length <= 100
    • strs[i] consists of lower-case English letters.

    字母异位词分组。

    给定一个字符串数组,将字母异位词组合在一起。可以按任意顺序返回结果列表。字母异位词指字母相同,但排列不同的字符串。

    做这个题之前,需要做如下几个题,对anagram的概念有所了解。

    242. Valid Anagram

    383. Ransom Note

    387. First Unique Character in a String

    此题比较粗暴的解法是把 input 里面所有的单词都按照字母排序,形成一个新的单词。比如"eat"排序后会成为"aet",然后以"aet"为key,"eat"为 value 加入 hashmap。遍历完 input 之后,输出 hashmap 所有的 value 即可。

    时间O(nlogn) - sort

    空间O(n) - hashmap

    JavaScript实现

     1 /**
     2  * @param {string[]} strs
     3  * @return {string[][]}
     4  */
     5 var groupAnagrams = function (strs) {
     6     const map = {};
     7     for (let str of strs) {
     8         const key = [...str].sort().join('');
     9         if (!map[key]) {
    10             map[key] = [];
    11         }
    12         map[key].push(str);
    13     }
    14     return Object.values(map);
    15 };

    Java实现

     1 class Solution {
     2     public List<List<String>> groupAnagrams(String[] strs) {
     3         // corner case
     4         if (strs == null || strs.length == 0) {
     5             return new ArrayList<List<String>>();
     6         }
     7 
     8         // normal case
     9         HashMap<String, List<String>> map = new HashMap<>();
    10         for (String str : strs) {
    11             char[] ca = str.toCharArray();
    12             Arrays.sort(ca);
    13             String keyStr = String.valueOf(ca);
    14             if (!map.containsKey(keyStr)) {
    15                 map.put(keyStr, new ArrayList<String>());
    16             }
    17             map.get(keyStr).add(str);
    18         }
    19         return new ArrayList<List<String>>(map.values());
    20     }
    21 }

    但是如上不是最优解,最优解还是要通过counting sort的思路来做。对于每个单词,需要创建一个长度为26的数组(题目说了只有小写)来存这个单词里面每个字母都分别出现过几次。这样每个单词最后形成的数组会长类似这样,

    [ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ]
    [ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ]
    [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ]

    然后把这个数组稍微变化一下,做成一个类似这样的string

    1#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0

    把这个string当做hashmap的key。这样每个扫描过的单词都会变成这样,是错位词的单词们的string会长得一样,所以在hashmap中会被存到同一个key里面。最后以数组形式输出hashmap里面所有的value即可。或者中间不加#也能做,只需要把charArray convert成string即可,把这个string当做key存入hashmap。

    时间O(n) - 没有排序

    空间O(n)

    JavaScript实现

     1 /**
     2  * @param {string[]} strs
     3  * @return {string[][]}
     4  */
     5 var groupAnagrams = function (strs) {
     6     const map = new Map();
     7     for (const s of strs) {
     8         const letters = Array(26).fill(0);
     9         for (const c of s) {
    10             letters[c.charCodeAt(0) - 97]++;
    11         }
    12         console.log(letters);
    13         const key = letters.join("#");
    14         console.log(key);
    15         let val = [];
    16         if (map.has(key)) {
    17             val = map.get(key);
    18         }
    19         val.push(s);
    20         map.set(key, val);
    21     }
    22 
    23     return Array.from(map.values());
    24 };

    Java实现

     1 class Solution {
     2     public List<List<String>> groupAnagrams(String[] strs) {
     3         // corner case
     4         if (strs == null || strs.length == 0) {
     5             return new ArrayList<>();
     6         }
     7 
     8         // normal case
     9         HashMap<String, List<String>> map = new HashMap<>();
    10         for (String str : strs) {
    11             char[] ca = new char[26];
    12             for (char c : str.toCharArray()) {
    13                 ca[c - 'a']++;
    14             }
    15             String key = String.valueOf(ca);
    16             if (!map.containsKey(key)) {
    17                 map.put(key, new ArrayList<>());
    18             }
    19             map.get(key).add(str);
    20         }
    21         return new ArrayList<>(map.values());
    22     }
    23 }

    LeetCode 题目总结

  • 相关阅读:
    IDEA中getgetServletContext()报错
    会话跟踪小结
    Sklearn-CrossValidation交叉验证
    js定时器 数码时钟
    centos7 新建用户并获取root权限
    linux cetos7 yum 安装redis
    mybatis 中 使用 List<Map<String,Object>> Map<String,Object>接收结果
    Mybatis resultMap 中 collection association 的用法
    各大型邮箱smtp服务器及端口收集: SMTP
    Mybatis 动态sql 示例 复杂类型对象 作为参数进行取值
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12231788.html
Copyright © 2011-2022 走看看