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 []
.
public IList<string> GeneratePalindromes(string s) { List<string> result = new List<string>(); Dictionary<char, int> hashtable = new Dictionary<char, int>(); char[] cha = s.ToCharArray(); foreach(char a in cha) { if(hashtable.ContainsKey(a)) { int temp = (int)hashtable[a]; temp++; hashtable[a] = temp; } else { hashtable.Add(a,1); } } string middle = ""; char sentinel = '1'; int su = 0; foreach(char key in hashtable.Keys) { if(((int)hashtable[key])%2 == 1) { su++; middle += key; sentinel = key; } } if (su > 1) return result; if (su == 1) { int temp = (int)hashtable[sentinel]; temp--; if (temp == 0) hashtable.Remove(sentinel); else hashtable[sentinel] = temp; } GenerateNext(hashtable,result, new List<char>(),middle); return result; } private void GenerateNext(Dictionary<char, int> hashtable ,List<string> result ,List<char> cur, string middle) { if(hashtable.Count == 0) result.Add(new string(cur.ToArray())+middle + Reverse(new string(cur.ToArray()))); else { var tempHash = new Dictionary<char,int>(hashtable); foreach(char key in tempHash.Keys) { var hashtable1 = new Dictionary<char,int>(hashtable); if((int)hashtable1[key] >= 2) { int temp = (int)hashtable1[key]; temp -=2; if(temp == 0) hashtable1.Remove(key); else hashtable1[key] = temp; cur.Add(key); GenerateNext(hashtable1,result,cur,middle); cur.RemoveAt(cur.Count()-1); } } } } public int HashtableFirstVal(Dictionary<char, int> hashtable) { int sum = 0; foreach(int a in hashtable.Values) { sum += a; } return sum; } public char HashtableFirstKey(Dictionary<char, int> hashtable) { char sum = '1'; foreach(char a in hashtable.Keys) { sum = a; } return sum; } public string Reverse( string s ) { char[] charArray = s.ToCharArray(); Array.Reverse( charArray ); return new string( charArray ); }
或者用Backtracking
public IList<string> GeneratePalindromes(string s) { var res = new List<string>(); if(s == null) return res; var hashtable = new Dictionary<char,int>(); for(int i =0;i< s.Length;i++) { if(hashtable.ContainsKey(s[i])) hashtable[s[i]]++; else hashtable.Add(s[i],1); } int oddCount=0; var oddGroup = new Dictionary<char,int>(); var evenGroup = new Dictionary<char,int>(); foreach( var h in hashtable) { if(h.Value %2 == 0) evenGroup.Add(h.Key,h.Value); else { oddGroup.Add(h.Key,h.Value); oddCount++; } } if(oddCount > 1) return res; Backtracking("",res,oddGroup,evenGroup); return res; } private void Backtracking(string cur, List<string> res, Dictionary<char,int> odd,Dictionary<char,int> even) { if(odd.Count()== 0 && even.Count()==0) {res.Add(cur+ Reverse(cur)); return;} else if(even.Count()==0 && odd.Count()==1) { foreach( var o in odd) { if(o.Value==1) {res.Add(cur + o.Key + Reverse(cur)); return;} } } if(even.Count() != 0) { var tempEven = new Dictionary<char,int>(even); foreach(var e in even) { if(e.Value > 0) { tempEven[e.Key] -=2; if(tempEven[e.Key]==0) { tempEven.Remove(e.Key); Backtracking(cur+e.Key,res,odd,tempEven); tempEven.Add(e.Key,0); } else { Backtracking(cur+e.Key,res,odd,tempEven); } tempEven[e.Key] +=2; } } } var tempOdd = new Dictionary<char,int>(odd); foreach(var o in odd) { if(o.Value > 2) { //cur =cur + e.Key; tempOdd[o.Key] -=2; Backtracking(cur+o.Key,res,tempOdd,even); tempOdd[o.Key] +=2; } } } private string Reverse(string s) { if(s == null) return s; var c = s.ToCharArray(); Array.Reverse(c); return new string(c); }