[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 generatePalindromes(string s) {
        vector ret;
        string line(s);
        unordered_map 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 &ret, string &line, int index, 
                             unordered_map &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;
            }
        }
    }
};

你可能感兴趣的:(IT公司面试习题)