大前天作的一道题,昨天发版到11点,前天聚餐,一直没时间整理,今天下班闲来无事,仍是作个简单思路整理。本题来自LeetCode 451. 根据字符出现频率排序,难度中等,其实整理下思路,其实并不算难,题目描述以下:数组
贰 ❀ 题解分析给定一个字符串,请将字符串里的字符按照出现的频率降序排列。数据结构
示例 1:ide
输入: "tree" 输出: "eert" 解释: 'e'出现两次,'r'和't'都只出现一次。 所以'e'必须出如今'r'和't'以前。此外,"eetr"也是一个有效的答案。示例 2:优化
输入: "cccaaa" 输出: "cccaaa" 解释: 'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。 注意"cacaca"是不正确的,由于相同的字母必须放在一块儿。示例 3:code
输入: "Aabb" 输出: "bbAa" 解释: 此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。 注意'A'和'a'被认为是两种不一样的字符。
题意很简单,给定一个字符串,请统计字符串中每种字符出现的次数,并按照由高到低的顺序重组字符并返回,好比tree能够返回为eetr或者eert,也就是说出现次数相同的字符不用考虑前后顺序,前面两种答案均符合条件。对象
直观思路其实很简单,统计每一个字符出现的次数,好比't:1','r:1','e:2',而后对其进行排序,数字越高的在前面,最后咱们再进行字符重组,好比e有2个,所以相加2次,依次操做获得最终字符。排序
那么问题就来了,咱们使用什么数据结构来统计字符的次数呢?直觉可能想到的是对象,好比:字符串
let map = { t:1, r:1, e:2 }
望着统计完成后对象,排序又成了问题....倒不是不能排,而是有点麻烦。因此思考了下,仍是选用map结构,理由是咱们能够经过...直接将map转为数组,方便一点,原本觉得是暴力解法,最后看了下你们的思路,都大同小异,其实还击败了九十多的人,贴下代码:get
/** * @param {string} s * @return {string} */ var frequencySort = function (s) { // 用来统计字符次数用 let map = new Map(); let res = ''; for (let k = 0; k < s.length; k++) { map.set(s[k], (map.get(s[k]) || 0) + 1) } // 排序,让字符多的在前面 let arr = [...map].sort((a, b) => { return b[1] - a[1]; }); // 字符串重组 for (let i = 0; i < arr.length; i++) { while (arr[i][1] > 0) { res += arr[i][0]; arr[i][1]--; } } return res; };
其实这里有个代码简写的优化点,我最初对于判断map中是否包含了某个字符,没有设置为1,有则加1的写法是这样:string
if (map.get(s[k])) { map.set(s[k], map.get(s[k]) + 1) } else { map.set(s[k], 1); }
其实经过||能够简化成一句,有就之前面的值为准加1,没有则取0加1做为最初的值,至关人性化,那么就记录到这里了。