logo

文字列から文字を削除またはシャッフルして形成された最長の回文を検索します

与えられた文字列から、文字列から文字を削除またはシャッフルすることによって構築できる最長の回文を見つけます。最長の長さの回文文字列が複数ある場合は、回文を 1 つだけ返します。

例: 



Androidプロセスacoreが停止し続ける
  Input:    abc   Output:   a OR b OR c   Input:    aabbcc   Output:   abccba OR baccab OR cbaabc OR any other palindromic string of length 6.   Input:    abbaccd   Output:   abcdcba OR ...   Input:    aba   Output:   aba

回文文字列は、中間部と末尾の 3 つの部分に分割できます。奇数長の回文文字列の場合、2n + 1 の「beg」は文字列の最初の n 文字で構成され、「mid」は 1 文字のみ、つまり (n + 1) 番目の文字で構成され、「end」は回文文字列の最後の n 文字で構成されます。偶数長さの回文文字列 2n の場合、「mid」は常に空になります。文字列を回文にするために、「end」は「beg」の逆になることに注意してください。

アイデアは、上記の観察をソリューションに使用することです。文字のシャッフルが許可されているため、入力文字列では文字の順序は関係ありません。まず、入力文字列内の各文字の頻度を取得します。そうすれば、n 文字を「beg」文字列に、残りの n 文字を「end」文字列に (回文順序を維持することにより) 簡単に配置できるため、入力文字列内で偶数出現 (たとえば 2n) したすべての文字が出力文字列の一部になります。奇数に出現する文字 (たとえば 2n + 1) の場合は、「mid」をそのような文字すべての 1 つで埋めます。残りの 2n 文字は半分に分割され、先頭と末尾に追加されます。

JavaScriptのオンロード

以下は上記のアイデアの実装です 



C++
// C++ program to find the longest palindrome by removing // or shuffling characters from the given string #include    using namespace std; // Function to find the longest palindrome by removing // or shuffling characters from the given string string findLongestPalindrome(string str) {  // to stores freq of characters in a string  int count[256] = { 0 };  // find freq of characters in the input string  for (int i = 0; i < str.size(); i++)  count[str[i]]++;  // Any palindromic string consists of three parts  // beg + mid + end  string beg = '' mid = '' end = '';  // solution assumes only lowercase characters are  // present in string. We can easily extend this  // to consider any set of characters  for (char ch = 'a'; ch <= 'z'; ch++)  {  // if the current character freq is odd  if (count[ch] & 1)  {  // mid will contain only 1 character. It  // will be overridden with next character  // with odd freq  mid = ch;  // decrement the character freq to make  // it even and consider current character  // again  count[ch--]--;  }  // if the current character freq is even  else  {  // If count is n(an even number) push  // n/2 characters to beg string and rest  // n/2 characters will form part of end  // string  for (int i = 0; i < count[ch]/2 ; i++)  beg.push_back(ch);  }  }  // end will be reverse of beg  end = beg;  reverse(end.begin() end.end());  // return palindrome string  return beg + mid + end; } // Driver code int main() {  string str = 'abbaccd';  cout << findLongestPalindrome(str);  return 0; } 
Java
// Java program to find the longest palindrome by removing // or shuffling characters from the given string class GFG { // Function to find the longest palindrome by removing // or shuffling characters from the given string  static String findLongestPalindrome(String str) {  // to stores freq of characters in a string  int count[] = new int[256];  // find freq of characters in the input string  for (int i = 0; i < str.length(); i++) {  count[str.charAt(i)]++;  }  // Any palindromic string consists of three parts  // beg + mid + end  String beg = '' mid = '' end = '';  // solution assumes only lowercase characters are  // present in string. We can easily extend this  // to consider any set of characters  for (char ch = 'a'; ch <= 'z'; ch++) {  // if the current character freq is odd  if (count[ch] % 2 == 1) {  // mid will contain only 1 character. It  // will be overridden with next character  // with odd freq  mid = String.valueOf(ch);  // decrement the character freq to make  // it even and consider current character  // again  count[ch--]--;  } // if the current character freq is even  else {  // If count is n(an even number) push  // n/2 characters to beg string and rest  // n/2 characters will form part of end  // string  for (int i = 0; i < count[ch] / 2; i++) {  beg += ch;  }  }  }  // end will be reverse of beg  end = beg;  end = reverse(end);  // return palindrome string  return beg + mid + end;  }  static String reverse(String str) {  // convert String to character array   // by using toCharArray   String ans = '';  char[] try1 = str.toCharArray();  for (int i = try1.length - 1; i >= 0; i--) {  ans += try1[i];  }  return ans;  }  // Driver code  public static void main(String[] args) {  String str = 'abbaccd';  System.out.println(findLongestPalindrome(str));  } } // This code is contributed by PrinciRaj1992 
Python3
# Python3 program to find the longest palindrome by removing # or shuffling characters from the given string # Function to find the longest palindrome by removing # or shuffling characters from the given string def findLongestPalindrome(strr): # to stores freq of characters in a string count = [0]*256 # find freq of characters in the input string for i in range(len(strr)): count[ord(strr[i])] += 1 # Any palindromic consists of three parts # beg + mid + end beg = '' mid = '' end = '' # solution assumes only lowercase characters are # present in string. We can easily extend this # to consider any set of characters ch = ord('a') while ch <= ord('z'): # if the current character freq is odd if (count[ch] & 1): # mid will contain only 1 character. It # will be overridden with next character # with odd freq mid = ch # decrement the character freq to make # it even and consider current character # again count[ch] -= 1 ch -= 1 # if the current character freq is even else: # If count is n(an even number) push # n/2 characters to beg and rest # n/2 characters will form part of end # string for i in range(count[ch]//2): beg += chr(ch) ch += 1 # end will be reverse of beg end = beg end = end[::-1] # return palindrome string return beg + chr(mid) + end # Driver code strr = 'abbaccd' print(findLongestPalindrome(strr)) # This code is contributed by mohit kumar 29 
C#
// C# program to find the longest  // palindrome by removing or // shuffling characters from  // the given string using System; class GFG {  // Function to find the longest   // palindrome by removing or   // shuffling characters from   // the given string  static String findLongestPalindrome(String str)   {  // to stores freq of characters in a string  int []count = new int[256];  // find freq of characters   // in the input string  for (int i = 0; i < str.Length; i++)   {  count[str[i]]++;  }  // Any palindromic string consists of   // three parts beg + mid + end  String beg = '' mid = '' end = '';  // solution assumes only lowercase   // characters are present in string.  // We can easily extend this to   // consider any set of characters  for (char ch = 'a'; ch <= 'z'; ch++)     {  // if the current character freq is odd  if (count[ch] % 2 == 1)   {    // mid will contain only 1 character.   // It will be overridden with next   // character with odd freq  mid = String.Join(''ch);  // decrement the character freq to make  // it even and consider current   // character again  count[ch--]--;  }     // if the current character freq is even  else   {    // If count is n(an even number) push  // n/2 characters to beg string and rest  // n/2 characters will form part of end  // string  for (int i = 0; i < count[ch] / 2; i++)   {  beg += ch;  }  }  }  // end will be reverse of beg  end = beg;  end = reverse(end);  // return palindrome string  return beg + mid + end;  }  static String reverse(String str)   {  // convert String to character array   // by using toCharArray   String ans = '';  char[] try1 = str.ToCharArray();  for (int i = try1.Length - 1; i >= 0; i--)   {  ans += try1[i];  }  return ans;  }  // Driver code  public static void Main()   {  String str = 'abbaccd';  Console.WriteLine(findLongestPalindrome(str));  } } // This code is contributed by 29AjayKumar 
JavaScript
<script> // Javascript program to find the  // longest palindrome by removing // or shuffling characters from  // the given string // Function to find the longest  // palindrome by removing // or shuffling characters from // the given string  function findLongestPalindrome(str)  {  // to stores freq of characters   // in a string  let count = new Array(256);  for(let i=0;i<256;i++)  {  count[i]=0;  }    // find freq of characters in   // the input string  for (let i = 0; i < str.length; i++) {  count[str[i].charCodeAt(0)]++;  }    // Any palindromic string consists  // of three parts  // beg + mid + end  let beg = '' mid = '' end = '';    // solution assumes only   // lowercase characters are  // present in string.   // We can easily extend this  // to consider any set of characters  for (let ch = 'a'.charCodeAt(0);   ch <= 'z'.charCodeAt(0); ch++) {  // if the current character freq is odd  if (count[ch] % 2 == 1) {  // mid will contain only 1 character. It  // will be overridden with next character  // with odd freq  mid = String.fromCharCode(ch);    // decrement the character freq to make  // it even and consider current character  // again  count[ch--]--;  } // if the current character freq is even  else {  // If count is n(an even number) push  // n/2 characters to beg string and rest  // n/2 characters will form part of end  // string  for (let i = 0; i < count[ch] / 2; i++)   {  beg += String.fromCharCode(ch);  }  }  }    // end will be reverse of beg  end = beg;  end = reverse(end);    // return palindrome string  return beg + mid + end;  }    function reverse(str)  {  // convert String to character array   // by using toCharArray   let ans = '';  let try1 = str.split('');    for (let i = try1.length - 1; i >= 0; i--) {  ans += try1[i];  }  return ans;  }    // Driver code  let str = 'abbaccd';  document.write(findLongestPalindrome(str));    // This code is contributed by unknown2108   </script> 

出力
abcdcba

時間計算量 上記の解決策は O(n) です。ここで、n は文字列の長さです。アルファベットの文字数は一定であるため、漸近分析には寄与しません。
補助スペース プログラムで使用されるのは M です。M は ASCII 文字の数です。