【程序员面试金典】【字符串】面试题 10.02 - 变位词组

一 目录

不折腾的前端,和咸鱼有什么区别

目录
一 目录
二 题目
三 解题思路
四 统计分析
五 解题套路

二 题目

编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。

变位词是指字母相同,但排列不同的字符串。

注意:本题相对原题稍作修改

示例:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]
说明:

所有输入均为小写字母。
不考虑答案输出的顺序。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/group-anagrams-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
/**
 * @param {string[]} strs
 * @return {string[][]}
 */
var groupAnagrams = function(strs) {

};

根据上面的已知函数,小伙伴们可以先尝试破解本题,确定了自己的答案后再看下面代码。

三 解题思路

拿到题目写了个乱七八糟的递归:

18:00 解法 1:递归(超时)

const groupAnagrams = (strs) => {
  const result = [];
  const ergodic = (strs, nextStr = [], tempStr = []) => {
    if (!strs.length) {
      return;
    }
    tempStr.push(strs[0]);
    const temp = strs[0].split('').sort().join('');
    for (let i = 1; i < strs.length; i++) {
      if (strs[i].split('').sort().join('') === temp) {
        tempStr.push(strs[i]);
      } else {
        nextStr.push(strs[i]);
      }
    }
    result.push(tempStr);
    ergodic(nextStr, [], []);
  };
  ergodic(strs, [], []);
  return result;
};

虽然它是可以跑的,但是它超时了(别上,那个测试用例很恐怖)~

然后稍微优化了下,别思考那么多:

31:27 解法 2:哈希表(未完成版)

const groupAnagrams = (strs) => {
  // 假设我有一堆框
  const result = [];
  // 假设我有一本好字典
  const map = new Map();
  // 假设数组不是变位词,而是相同字符串
  for (let i = 0; i < strs.length; i++) {
    // 假设字典尚未记录
    if (map.get(strs[i]) === undefined) {
      map.set(strs[i], result.length);
      result.push([strs[i]]);
    } else {
      result[map.get(strs[i])].push(strs[i]);
    }
  }
  // 返回最终结果
  return result;
};

console.log(groupAnagrams(["eat", "eat", "tan", "eat", "tan", "bat"]));
// [ [ 'eat', 'eat', 'eat' ], [ 'tan', 'tan' ], [ 'bat' ] ]

这里咱先不考虑异位词问题,咱们一视同仁,将它看成一样的!

看到这里,相比各位小伙伴有点思路了,只需要进行最后一步小优化:

36:00 解法 2:哈希表(完成版)

const groupAnagrams = (strs) => {
  // 假设我有一堆框
  const result = [];
  // 假设我有一本好字典
  const map = new Map();
  // 假设数组不是变位词,而是相同字符串
  for (let i = 0; i < strs.length; i++) {
    const temp = strs[i].split('').sort().join('');
    // 假设字典尚未记录
    if (map.get(temp) === undefined) {
      map.set(temp, result.length);
      result.push([strs[i]]);
    } else {
      result[map.get(temp)].push(strs[i]);
    }
  }
  // 返回最终结果
  return result;
};

提交上去:

执行结果:通过
执行用时:108 ms, 在所有 JavaScript 提交中击败了 100.00% 的用户
内存消耗:46.4 MB, 在所有 JavaScript 提交中击败了 100.00% 的用户

打完收工。

四 统计分析

本题暂不需要统计分析~

五 套路分析

本题暂未发现任何套路,如果有但是 jsliang 后面发现了的话,会在 GitHub 进行补充。

如果小伙伴有更好的思路想法,或者没看懂其中某种解法,欢迎评论留言或者私聊 jsliang~


不折腾的前端,和咸鱼有什么区别!

jsliang 会每天更新一道 LeetCode 题解,从而帮助小伙伴们夯实原生 JS 基础,了解与学习算法与数据结构。

浪子神剑 会每天更新面试题,以面试题为驱动来带动大家学习,坚持每天学习与思考,每天进步一点!

扫描上方二维码,关注 jsliang 的公众号(左)和 浪子神剑 的公众号(右),让我们一起折腾!

jsliang 的文档库 由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于https://github.com/LiangJunrong/document-library上的作品创作。
本许可协议授权之外的使用权限可以从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处获得。

你可能感兴趣的:(【程序员面试金典】【字符串】面试题 10.02 - 变位词组)