壹 ❀ 引
大前天做的一道題,昨天發版到11點,前天聚餐,一直沒時間整理,今天下班閑來無事,還是做個簡單思路整理。本題來自LeetCode 451. 根據字符出現頻率排序,難度中等,其實整理下思路,其實並不算難,題目描述如下:
給定一個字符串,請將字符串里的字符按照出現的頻率降序排列。
示例 1:
輸入: "tree" 輸出: "eert" 解釋: 'e'出現兩次,'r'和't'都只出現一次。 因此'e'必須出現在'r'和't'之前。此外,"eetr"也是一個有效的答案。
示例 2:
輸入: "cccaaa" 輸出: "cccaaa" 解釋: 'c'和'a'都出現三次。此外,"aaaccc"也是有效的答案。 注意"cacaca"是不正確的,因為相同的字母必須放在一起。
示例 3:
輸入: "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
轉為數組,方便一點,本來以為是暴力解法,最后看了下大家的思路,都大同小異,其實還擊敗了九十多的人,貼下代碼:
/**
* @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的寫法是這樣:
if (map.get(s[k])) {
map.set(s[k], map.get(s[k]) + 1)
} else {
map.set(s[k], 1);
}
其實通過||
可以簡化成一句,有就以前面的值為准加1,沒有則取0加1作為最初的值,相當人性化,那么就記錄到這里了。