[Leetcode] 267. Palindrome Permutation II 解题报告

题目

Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empty list if no palindromic permutation could be form.

For example:

Given s = "aabb", return ["abba", "baab"].

Given s = "abc", return [].

思路

由于是需要得到所有符合要求的答案,所以很自然的可以想到BackTracking。思路是:首先判断是否可以构成合法的回文数(用Palindrome Permutation I的思路),如果无法构成,则返回。否则,如果有一个字符出现了奇数次,则把它首先放在字符串的最中间。然后再用类似于DFS的方法,依次从0到s.length() / 2 - 1放置当前哈希表中还剩余的字符(对于回文串而言,一旦前一半的字符确定了,则后一半的字符也必然确定无疑了)。最关键的一步是,调用下一层的DFS之后,记得恢复计数,这样在尝试下一个字符的时候,计数器才是正确的。

代码

class Solution {
public:
    vector<string> generatePalindromes(string s) {
        vector<string> ret;
        string line(s);
        unordered_map<char, int> hash;
        for (auto val : s) {
            ++hash[val];
        }
        int odd_num = 0;
        char odd_char = ' ';
        for (auto it = hash.begin(); it != hash.end(); ++it) {
            if (it->second % 2 != 0) {
                ++odd_num;
                odd_char = it->first;
            }
        }
        if (odd_num > 1) {
            return {};
        }
        else if (odd_num == 1) {
            line[s.length() / 2] = odd_char;
            --hash[odd_char];
        }
        generatePalindromes(ret, line, 0, hash);
        return ret;
    }
private:
    void generatePalindromes(vector<string> &ret, string &line, int index, 
                             unordered_map<char, int> &hash) {
        int length = line.length();
        if (index == length / 2) {
            ret.push_back(line);
            return;
        }
        for (auto it = hash.begin(); it != hash.end(); ++it) {
            if (it->second > 0) {
                line[index] = line[length - 1 - index] = it->first;
                it->second -= 2;
                generatePalindromes(ret, line, index + 1, hash);
                it->second += 2;
            }
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值