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

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

例: 

  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 文字は半分に分割され、先頭と末尾に追加されます。

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

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 文字の数です。