[面试算法题]根据字符出现频率排序

119 阅读2分钟

给定一个字符串 s ,根据字符出现的 频率 对其进行降序排序 。一个字符出现的频率是它出现在字符串中的次数。

返回 已排序的字符串 。如果有多个答案,返回其中任何一个。

示例 1:

    输入: s = "tree"

    输出: "eert"

    解释: 'e'出现两次,'r'和't'都只出现一次。

    因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。

示例 2:

    输入: s = "cccaaa"

    输出: "cccaaa"

    解释: 'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。

    注意"cacaca"是不正确的,因为相同的字母必须放在一起。

示例 3:

    输入: s = "Aabb"

    输出: "bbAa"

    解释: 此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。

    注意'A'和'a'被认为是两种不同的字符。

提示:

    1 <= s.length <= 5 * 105

    s 由大小写英文字母和数字组成

以下是使用JavaScript编写的frequencySort函数,该函数接受一个字符串作为输入,并根据字符出现的频率进行降序排序:

function frequencySort(s) {
  // 使用一个对象来存储字符及其频率
  const freqMap = {};
  for (let char of s) {
    freqMap[char] = (freqMap[char] || 0) + 1;
  }

  // 将字符和频率转换为数组
  const charFreqArray = Object.entries(freqMap);

  // 对数组进行排序,首先根据频率降序排序,然后如果频率相同则根据字符的Unicode码点升序排序
  charFreqArray.sort((a, b) => {
    if (a[1] === b[1]) {
      return a[0].localeCompare(b[0]); // 使用localeCompare保持原始顺序(如果字符相同则顺序不变)
    }
    return b[1] - a[1]; // 频率降序排序
  });

  // 根据排序后的数组重新构建字符串
  let sortedString = '';
  for (let [char, freq] of charFreqArray) {
    sortedString += char.repeat(freq);
  }

  return sortedString;
}

// 示例测试
console.log(frequencySort("tree"));      // 输出: eert 或其他有效答案
console.log(frequencySort("cccaaa"));    // 输出: cccaaa 或其他有效答案
console.log(frequencySort("Aabb"));      // 输出: bbAa 或其他有效答案

在这个JavaScript实现中,我们首先遍历输入字符串s并使用一个对象freqMap来存储每个字符及其出现的频率。然后,我们将这个对象转换为数组charFreqArray,其中每个元素都是一个包含字符和频率的数组。接下来,我们对这个数组进行排序,首先根据频率降序排序,然后在频率相同时根据字符的Unicode码点升序排序(这实际上保持了字符在原始字符串中的相对顺序,因为localeCompare对于相同字符会返回0)。最后,我们遍历排序后的数组并使用String.prototype.repeat方法根据频率将字符连接起来形成最终的排序字符串。