文字列が K-回文かどうかを調べる |セット2
与えられた文字列が K-回文であるかどうかを調べます。 K 回文文字列は、そこから最大 k 文字を削除すると回文に変換されます。
例:
Input : String - abcdecba k = 1 Output : Yes String can become palindrome by removing 1 character i.e. either d or e Input : String - abcdeca K = 2 Output : Yes Can become palindrome by removing 2 characters b and e (or b and d). Input : String - acdcb K = 1 Output : No String can not become palindrome by removing only one character.
DP ソリューションについては、 前の この問題は基本的に次のバリエーションであることがわかりました。 距離の編集 問題。この投稿では、別の興味深い DP ソリューションについて説明します。
目的は、指定された文字列の最長の回文部分シーケンスを見つけることです。最長の回文部分列と元の文字列の差が k 以下の場合、その文字列は k-回文であり、それ以外の場合は k-回文ではありません。
たとえば、文字列の最長回文サブシーケンス ABCデカ は accdca (またはアセカ)。文字列を回文にするために、文字列の最長の回文部分列に寄与しない文字を削除する必要があります。したがって、abcdeca 文字列から b と d (または e) を削除すると、回文に変換されます。
文字列の最長の回文部分シーケンスは、次の方法で簡単に見つけることができます。 LCS 。以下は、LCS を使用して最長の回文部分配列を見つけるための 2 段階のソリューションです。
- 指定されたシーケンスを反転し、その反転を別の配列 (rev[0..n-1] など) に保存します。
- 指定されたシーケンスの LCS と rev[] が最長の回文シーケンスになります。
以下は上記のアイデアの実装です –
// C++ program to find if given string is K-Palindrome // or not #include using namespace std ; /* Returns length of LCS for X[0..m-1] Y[0..n-1] */ int lcs ( string X string Y int m int n ) { int L [ m + 1 ][ n + 1 ]; /* Following steps build L[m+1][n+1] in bottom up fashion. Note that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */ for ( int i = 0 ; i <= m ; i ++ ) { for ( int j = 0 ; j <= n ; j ++ ) { if ( i == 0 || j == 0 ) L [ i ][ j ] = 0 ; else if ( X [ i - 1 ] == Y [ j - 1 ]) L [ i ][ j ] = L [ i - 1 ][ j - 1 ] + 1 ; else L [ i ][ j ] = max ( L [ i - 1 ][ j ] L [ i ][ j - 1 ]); } } // L[m][n] contains length of LCS for X and Y return L [ m ][ n ]; } // find if given string is K-Palindrome or not bool isKPal ( string str int k ) { int n = str . length (); // Find reverse of string string revStr = str ; reverse ( revStr . begin () revStr . end ()); // find longest palindromic subsequence of // given string int lps = lcs ( str revStr n n ); // If the difference between longest palindromic // subsequence and the original string is less // than equal to k then the string is k-palindrome return ( n - lps <= k ); } // Driver program int main () { string str = 'abcdeca' ; int k = 2 ; isKPal ( str k ) ? cout < < 'Yes' : cout < < 'No' ; return 0 ; }
Java // Java program to find if given // String is K-Palindrome or not import java.util.* ; import java.io.* ; class GFG { /* Returns length of LCS for X[0..m-1] Y[0..n-1] */ static int lcs ( String X String Y int m int n ) { int L [][] = new int [ m + 1 ][ n + 1 ] ; /* Following steps build L[m+1][n+1] in bottom up fashion. Note that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */ for ( int i = 0 ; i <= m ; i ++ ) { for ( int j = 0 ; j <= n ; j ++ ) { if ( i == 0 || j == 0 ) { L [ i ][ j ] = 0 ; } else if ( X . charAt ( i - 1 ) == Y . charAt ( j - 1 )) { L [ i ][ j ] = L [ i - 1 ][ j - 1 ] + 1 ; } else { L [ i ][ j ] = Math . max ( L [ i - 1 ][ j ] L [ i ][ j - 1 ] ); } } } // L[m][n] contains length // of LCS for X and Y return L [ m ][ n ] ; } // find if given String is // K-Palindrome or not static boolean isKPal ( String str int k ) { int n = str . length (); // Find reverse of String StringBuilder revStr = new StringBuilder ( str ); revStr = revStr . reverse (); // find longest palindromic // subsequence of given String int lps = lcs ( str revStr . toString () n n ); // If the difference between longest // palindromic subsequence and the // original String is less than equal // to k then the String is k-palindrome return ( n - lps <= k ); } // Driver code public static void main ( String [] args ) { String str = 'abcdeca' ; int k = 2 ; if ( isKPal ( str k )) { System . out . println ( 'Yes' ); } else System . out . println ( 'No' ); } } // This code is contributed by Rajput-JI
Python3 # Python program to find # if given string is K-Palindrome # or not # Returns length of LCS # for X[0..m-1] Y[0..n-1] def lcs ( X Y m n ): L = [[ 0 ] * ( n + 1 ) for _ in range ( m + 1 )] # Following steps build # L[m+1][n+1] in bottom up # fashion. Note that L[i][j] # contains length of # LCS of X[0..i-1] and Y[0..j-1] for i in range ( m + 1 ): for j in range ( n + 1 ): if not i or not j : L [ i ][ j ] = 0 elif X [ i - 1 ] == Y [ j - 1 ]: L [ i ][ j ] = L [ i - 1 ][ j - 1 ] + 1 else : L [ i ][ j ] = max ( L [ i - 1 ][ j ] L [ i ][ j - 1 ]) # L[m][n] contains length # of LCS for X and Y return L [ m ][ n ] # find if given string is # K-Palindrome or not def isKPal ( string k ): n = len ( string ) # Find reverse of string revStr = string [:: - 1 ] # find longest palindromic # subsequence of # given string lps = lcs ( string revStr n n ) # If the difference between # longest palindromic # subsequence and the original # string is less # than equal to k then # the string is k-palindrome return ( n - lps <= k ) # Driver program string = 'abcdeca' k = 2 print ( 'Yes' if isKPal ( string k ) else 'No' ) # This code is contributed # by Ansu Kumari.
C# // C# program to find if given // String is K-Palindrome or not using System ; class GFG { /* Returns length of LCS for X[0..m-1] Y[0..n-1] */ static int lcs ( String X String Y int m int n ) { int [] L = new int [ m + 1 n + 1 ]; /* Following steps build L[m+1n+1] in bottom up fashion. Note that L[ij] contains length of LCS of X[0..i-1] and Y[0..j-1] */ for ( int i = 0 ; i <= m ; i ++ ) { for ( int j = 0 ; j <= n ; j ++ ) { if ( i == 0 || j == 0 ) { L [ i j ] = 0 ; } else if ( X [ i - 1 ] == Y [ j - 1 ]) { L [ i j ] = L [ i - 1 j - 1 ] + 1 ; } else { L [ i j ] = Math . Max ( L [ i - 1 j ] L [ i j - 1 ]); } } } // L[mn] contains length // of LCS for X and Y return L [ m n ]; } // find if given String is // K-Palindrome or not static bool isKPal ( String str int k ) { int n = str . Length ; // Find reverse of String str = reverse ( str ); // find longest palindromic // subsequence of given String int lps = lcs ( str str n n ); // If the difference between longest // palindromic subsequence and the // original String is less than equal // to k then the String is k-palindrome return ( n - lps <= k ); } static String reverse ( String input ) { char [] temparray = input . ToCharArray (); int left right = 0 ; right = temparray . Length - 1 ; for ( left = 0 ; left < right ; left ++ right -- ) { // Swap values of left and right char temp = temparray [ left ]; temparray [ left ] = temparray [ right ]; temparray [ right ] = temp ; } return String . Join ( '' temparray ); } // Driver code public static void Main ( String [] args ) { String str = 'abcdeca' ; int k = 2 ; if ( isKPal ( str k )) { Console . WriteLine ( 'Yes' ); } else Console . WriteLine ( 'No' ); } } // This code is contributed by PrinciRaj1992
JavaScript < script > // JavaScript program to find // if given string is K-Palindrome // or not // Returns length of LCS // for X[0..m-1] Y[0..n-1] function lcs ( X Y m n ){ let L = new Array ( m + 1 ); for ( let i = 0 ; i < m + 1 ; i ++ ){ L [ i ] = new Array ( n + 1 ). fill ( 0 ); } // Following steps build // L[m+1][n+1] in bottom up // fashion. Note that L[i][j] // contains length of // LCS of X[0..i-1] and Y[0..j-1] for ( let i = 0 ; i < m + 1 ; i ++ ) { for ( let j = 0 ; j < n + 1 ; j ++ ) { if ( ! i || ! j ) L [ i ][ j ] = 0 else if ( X [ i - 1 ] == Y [ j - 1 ]) L [ i ][ j ] = L [ i - 1 ][ j - 1 ] + 1 else L [ i ][ j ] = Math . max ( L [ i - 1 ][ j ] L [ i ][ j - 1 ]) } } // L[m][n] contains length // of LCS for X and Y return L [ m ][ n ] } // find if given string is // K-Palindrome or not function isKPal ( string k ){ let n = string . length // Find reverse of string let revStr = string . split ( '' ). reverse (). join ( '' ) // find longest palindromic // subsequence of // given string let lps = lcs ( string revStr n n ) // If the difference between // longest palindromic // subsequence and the original // string is less // than equal to k then // the string is k-palindrome return ( n - lps <= k ) } // Driver program let string = 'abcdeca' let k = 2 document . write ( isKPal ( string k ) ? 'Yes' : 'No' ) // This code is contributed by shinjanpatra < /script>
出力
Yes
時間計算量 上記の解は O(n 2 )。
補助スペース プログラムで使用されるのは O(n 2 )。次を使用すると、さらに O(n) に減らすことができます。 LCS のスペース最適化ソリューション 。
おかげで あなたが狭くなった峡谷 上記の解決策を提案していただきました。