LeetCode 算法:回文排列

126 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 4 天,点击查看活动详情

回文排列

原题地址

给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。

回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。

回文串不一定是字典当中的单词。

示例1:

输入:"tactcoa"
输出:true(排列有"tacocat""atcocta",等等)

示例2:

输入:"code"
输出:false

思路分析

方法一

  1. 分析题目满足回文排列的条件,可以得知若一个字符串是回文排列的字符串,那么它含有的字母中每个字母的数量都为偶数或者只有一个字母的数量为奇数,只有这两种情况下才会是回文排列;
  2. 定义一个 map 来存储字符串中字符出现的次数,以字符为 key,次数为 value 存储;
  3. 使用 Object.values(map) 得到字幕出现次数的数组,将奇数的元素过滤出来;
  4. 判断奇数元素的长度是否为 0 或者 1

方法二

  1. 按照方法一的判断情况定义一个 map 来存储字符串中字符出现的情况;
  2. 遍历字符串 s,若 map 中含有该字母,则将对应的 key 删掉,否则 map[s[i]] = 1
  3. 判断最后得到的 map 含有的 key0 或者 1

AC 代码

方法一

/**
 * @param {string} s
 * @return {boolean}
 */
var canPermutePalindrome = function(s) {
    const map = {}
    for(let i = 0; i < s.length; i++) {
        if(map[s[i]]) {
            map[s[i]] += 1
        } else {
            map[s[i]] = 1
        }
    }
    const odd = Object.values(map).filter(item => item % 2 === 1)
    return odd.length === 0 || odd.length === 1
};

结果:

  • 执行结果: 通过
  • 执行用时:52 ms, 在所有 JavaScript 提交中击败了93.16%的用户
  • 内存消耗:40.9 MB, 在所有 JavaScript 提交中击败了79.30%的用户
  • 通过测试用例:27 / 27

方法二

/**
 * @param {string} s
 * @return {boolean}
 */
var canPermutePalindrome = function(s) {
    const map = {}
    for(let i = 0; i < s.length; i++) {
        if(map[s[i]]) {
            delete map[s[i]]
        } else {
            map[s[i]] = 1
        }
    }
    const odd = Object.values(map)
    return odd.length === 0 || odd.length === 1
};

结果:

  • 执行结果: 通过
  • 执行用时:64 ms, 在所有 JavaScript 提交中击败了35.94%的用户
  • 内存消耗:41.1 MB, 在所有 JavaScript 提交中击败了46.48%的用户
  • 通过测试用例:27 / 27

END