[LeetCode][String][Recursive] 267. Palindrome Permutation II

Problem

More LeetCode Discussions

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 [].

Solution

  1. 判断回文
    先判断能否生成回文数,条件是所有的char都出现偶数次,如果有奇数次的char,必须只能有一个。否则就无法构成回文。
  2. 构造回文
    可以只构造前半部分,就是一个构造排列组合的过程。这里有一个技巧,比如有字符串aa,那么当我们要使用第二个a的时候,必须确保第一个a已经被使用了,这样就能有效避免重复的回文出现。另外如果有基数的char,那么必定出现在整个字符串的中间。
class Solution {
private:
    map<char, int> count;
    vector<char> chars;
    vector<bool> canUse;
    vector<string> ret;
    string result;
    char oddChar;
    int oddNum = 0;
public:
    void generate(int dep, int maxDep) {
        if (dep == maxDep) {
            if (oddNum > 0) {
                result[dep] = oddChar;
            }
            int j = result.size() - 1;
            for(int i = 0; i < maxDep; i++) {
                result[j] = result[i];
                j--;
            }
            ret.push_back(result);
            return;
        }    
        
        for(int i = 0; i < maxDep; i++) {
            if (canUse[i]) {
                if (i != 0 && chars[i] == chars[i-1] && canUse[i-1]) {
                    continue;
                }
                
                result[dep] = chars[i];
                canUse[i] = false;
                generate(dep + 1, maxDep);
                canUse[i] = true;
            }
        }
    }
    
    vector<string> generatePalindromes(string s) {
        for(int i = 0; i < s.size(); i++) {
            count[s[i]]++;
        }
        // check if it is valid
        for(map<char, int>::iterator iter = count.begin(); iter != count.end(); iter++) {
            if (iter->second % 2 == 1) {
                oddNum++;
                oddChar = iter->first;
            } 
            
            for(int i = 0; i < iter->second / 2; i++) {
                chars.push_back(iter->first);
            }
        }
        
        if (oddNum >= 2) {
            return ret;
        }
        
        canUse.resize(chars.size());
        for(int i = 0; i < canUse.size(); i++) {
            canUse[i] = true;
        }
        result = s; 
        generate(0, chars.size());
        
        return ret;
    }
};
    原文作者:楷书
    原文地址: https://www.jianshu.com/p/562dae09e3e7
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞