LeetCode算法学习之--HashMap--有效的字母异位词

233 阅读1分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

大家好今天给大家分享下一道 LeetCode 中等难度 的题目字母异位词分组

题目

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母都恰好只用一次。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:

输入: strs = [""]
输出: [[""]]
示例 3:

输入: strs = ["a"]
输出: [["a"]]

分析

1.异位词

1.长度相同

2.字母出现频率相同

2.把相同的异位词放在一个组

3.输出一个二维数组

4.字母全部为小写

解法

1.hashMap + 计数

2.hasMap+ sort

解法一:hashMap + 计数

1.第一次迭代 访问每个元素
2.使用map存储访问过的元素,
  1.先遍历map的key,看是否有存在异位词,如果有就 map.set(key, [...map.get(key), strs[i]]);
  2.如果遍历完了都没有 就创建一个新的map.set(strs[i], [strs[i]]);
3.比较异位词 我们还是使用 hashMap的方式来比较是否是异位词
*/

var groupAnagrams = function (strs) {
  const map = new Map();
  // 第一次迭代 访问每个元素
  for (let i = 0; i < strs.length; i++) {
    let isFindKey = false;
    // 先遍历map的key,看是否有存在异位词
    for (const key of map.keys()) {
      if (isAnagram(key, strs[i])) {
        map.set(key, [...map.get(key), strs[i]]);
        isFindKey = true;
      }
    }

    // 如果遍历完了都没有 就创建一个新的map.set(strs[i], [strs[i]]);
    if (!isFindKey) {
      map.set(strs[i], [strs[i]]);
    }
  }

  return Array.from(map.values());

  // 比较异位词 我们还是使用 hashMap的方式来比较是否是异位词
  function isAnagram(s, t) {
    if (s.length !== t.length) return false;
    const map = new Map();

    for (const char of s) {
      if (map.has(char)) map.set(char, map.get(char) + 1);
      else map.set(char, 1);
    }

    for (const char of t) {
      if (!map.has(char) || map.get(char) === 0) {
        return false;
      } else {
        map.set(char, map.get(char) - 1);
      }
    }

    return true;
  }
};

/* 复杂度
时间 O(n^2*m) n 数组的长度 m 字母的长度
空间 O(m*n)
*/

解法二:hashmap+sort

思路
1.第一次迭代 访问每个元素
2.使用map存储访问过的元素,
  1.先遍历map的key,看是否有存在异位词,如果有就 map.set(key, [...map.get(key), strs[i]]);
  2.如果遍历完了都没有 就创建一个新的map.set(strs[i], [strs[i]]);
3.比较异位词 我们还是使用 sort方式来比较是否是异位词
*/

var groupAnagrams = function (strs) {
  const map = new Map();
  // 第一次迭代 访问每个元素
  for (let i = 0; i < strs.length; i++) {
    let isFindKey = false;

    for (const key of map.keys()) {
      // 通过sort的方式来比较
      if (
        key.length === strs[i].length &&
        [...key].sort().join() === [...strs[i]].sort().join()
      ) {
        map.set(key, [...map.get(key), strs[i]]);
        isFindKey = true;
      }
    }

    // 如果遍历完了都没有 就创建一个新的map.set(strs[i], [strs[i]]);
    if (!isFindKey) {
      map.set(strs[i], [strs[i]]);
    }
  }

  return Array.from(map.values());
};

/* 复杂度
时间 O(n^2*m) n 数组的长度 m 字母的长度
空间 O(m*n)
*/

总结

这道题考察的在异位词的基础上增加了分组,这里的解法主要还是对异位词2种解法的应用 sort 和 计数

大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢

大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持

文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com