前端算法(41)

39 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目

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

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

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

题目解析

思路一

两个字母异位词所包含的字母是一样的,只是顺序不一样,所以我们可以对比排序后的字符串是否存在,如果存在,则往目标索引push当前项,如果不存在,数组push包含当前项的新数组,如果我们保存排序后的字符串和对应的索引,我们可以更精准的插入元素,我们可以用Map结构保存映射关系

var groupAnagrams = function (strs) {
  // map 存放对应关系索引
  const map = new Map()
  const res = []
  for(let i=0;i<strs.length;i++){
  // 将当前字符串从数组中取出并进行排序
    const sortedStr = strs[i].split('').sort().join('')
    // 如果哈希表中已经有此值,将当前字符串添加进去
    if(map.has(sortedStr)){
      const resIndex= map.get(sortedStr)
      res[resIndex].push(strs[i])
    }else {
    // 否则在哈希表中添加新的值
      res.push([strs[i]])
      map.set(sortedStr,res.length-1)
    }
  }
  return res
};

思路二

先定义一个compareArr变量用于放置排序后的不同字符串元素,遍历数组,获取当前字符串升序排列后的结果,获取在compareArr中的索引,索引为-1时,未出现过,compareArr追加结果字符串,result则增加新的子元素数组,数组内部元素为当前字符串,索引非-1时,在result对应位置的子数组中追加当前字符串

var groupAnagrams = function(strs) {
    let result = [], // 结果数组
        compareArr = []; // 用以比较的字符串数组
    strs.forEach(item => {
        // 获取当前字符串 => 按字母升序排列后的字符串
        let cur = item.split('').sort((a, b) => a.localeCompare(b)).join(''),
             // 获取在比较字符串数组中的索引
            index = compareArr.indexOf(cur);
        if(index === -1) { // 未出现过
            compareArr.push(cur); // 比较字符串增加
            result.push([item]); // 结果数组末尾增加
        } else { // 出现过
            result[index].push(item); // 在给定位置的子数组中继续追加
        }
    })
    return result;
};