logo

המספר המינימלי של תוספות הדרוש ליצירת פלינדרום מיתר

בהינתן א מחרוזת s המשימה היא למצוא את מִינִימוּם דמויות להיות מצורף (הוספה בסוף) לעשות פלינדרום מיתר. 

דוגמאות:  

קֶלֶט : s = 'בוצע'
תְפוּקָה : 2
הֶסבֵּר: אנחנו יכולים ליצור פלינדרום מיתרים בתור 'אבדי' לֹא ' על ידי הוספה לֹא בסוף המחרוזת.

קֶלֶט :s = 'aabb'
תְפוּקָה : 2
הֶסבֵּר: אנחנו יכולים ליצור פלינדרום מיתר אס'אב aa ' על ידי הוספה aa בסוף המחרוזת.



תוכן עניינים

בדוק פלינדרום בכל פעם - O(n^2) זמן ו-O(n) רווח

הפתרון כרוך בהדרגה הסרת תווים מה- רֵאשִׁית של המיתר אחד אחד עד שהמחרוזת הופכת ל-a פלינדרום . התשובה תהיה המספר הכולל של התווים שהוסר.

למשל, שקול את המחרוזת s = 'כאן'. קודם כל בודקים אם המיתר כולו הוא פלינדרום וזה לא. לאחר מכן נסיר את התו הראשון וכתוצאה מכך מחרוזת 'מתחנן'. אנחנו בודקים שוב אבל זה עדיין לא פלינדרום. לאחר מכן אנו מסירים דמות נוספת מההתחלה עוזב את 'אדה'. הפעם המיתר הוא פלינדרום. לכן ה הפלט הוא 2 מייצג את מספר התווים שהוסרו מההתחלה כדי להשיג פלינדרום.

C++
// C++ code to find minimum number  // of appends to make string Palindrome #include    using namespace std; // Function to check if a given string is a palindrome bool isPalindrome(string s) {  int left = 0 right = s.length() - 1;  while (left < right) {  if (s[left] != s[right]) return false;  left++;  right--;  }  return true; } // Function to find the minimum number of  // characters to remove from the beginning int noOfAppends(string& s) {  int n = s.length();    // Remove characters from the start until   // the string becomes a palindrome  for (int i = 0; i < n; i++) {  if (isPalindrome(s.substr(i))) {    // Return the number of characters removed  return i;   }  }    // If no palindrome is found remove  // all but one character  return n - 1;  } int main() {  string s = 'abede';  int result = noOfAppends(s);  cout << result << endl;  return 0; } 
Java
// Java code to find minimum number  // of appends to make string Palindrome import java.util.*; class GfG {    // Function to check if a given string is a palindrome  static boolean isPalindrome(String s) {  int left = 0 right = s.length() - 1;  while (left < right) {  if (s.charAt(left) != s.charAt(right)) return false;  left++;  right--;  }  return true;  }    // Function to find the minimum number of   // characters to remove from the beginning  static int noOfAppends(String s) {  int n = s.length();    // Remove characters from the start until   // the string becomes a palindrome  for (int i = 0; i < n; i++) {  if (isPalindrome(s.substring(i))) {    // Return the number of characters removed  return i;  }  }    // If no palindrome is found remove  // all but one character  return n - 1;  }  public static void main(String[] args) {  String s = 'abede';  int result = noOfAppends(s);  System.out.println(result);  } } 
Python
# Python code to find minimum number  # of appends to make string Palindrome # Function to check if a given string is a palindrome def is_palindrome(s): left right = 0 len(s) - 1 while left < right: if s[left] != s[right]: return False left += 1 right -= 1 return True # Function to find the minimum number of  # characters to remove from the beginning def no_of_appends(s): n = len(s) # Remove characters from the start until  # the string becomes a palindrome for i in range(n): if is_palindrome(s[i:]): # Return the number of characters # removed return i # If no palindrome is found remove # all but one character return n - 1 if __name__ == '__main__': s = 'abede' result = no_of_appends(s) print(result) 
C#
// C# code to find minimum number  // of appends to make string Palindrome using System; class GfG {    // Function to check if a given string   // is a palindrome  static bool IsPalindrome(string s) {  int left = 0 right = s.Length - 1;  while (left < right) {  if (s[left] != s[right]) return false;  left++;  right--;  }  return true;  }  // Function to find the minimum number of   // characters to remove from the beginning  static int NoOfAppends(string s) {  int n = s.Length;    // Remove characters from the start until   // the string becomes a palindrome  for (int i = 0; i < n; i++) {  if (IsPalindrome(s.Substring(i))) {    // Return the number of characters  // removed  return i;  }  }    // If no palindrome is found remove all but   // one character  return n - 1;  }  static void Main(string[] args) {  string s = 'abede';  int result = NoOfAppends(s);  Console.WriteLine(result);  } } 
JavaScript
// JavaScript code to find minimum number  // of appends to make string Palindrome // Function to check if a given string is a palindrome function isPalindrome(s) {  let left = 0 right = s.length - 1;  while (left < right) {  if (s[left] !== s[right]) return false;  left++;  right--;  }  return true; } // Function to find the minimum number of  // characters to remove from the beginning function noOfAppends(s) {  let n = s.length;    // Remove characters from the start until   // the string becomes a palindrome  for (let i = 0; i < n; i++) {  if (isPalindrome(s.substring(i))) {    // Return the number of  // characters removed  return i;  }  }    // If no palindrome is found remove  // all but one character  return n - 1; } const s = 'abede'; const result = noOfAppends(s); console.log(result); 

תְפוּקָה
2 

שימוש באלגוריתם Knuth Morris Pratt - O(n) זמן ו-O(n) Space

הרעיון הבסיסי מאחורי הגישה הוא שאנחנו לְחַשֵׁב את המחרוזת הגדולה ביותר מהסוף ואורך החוט מִינוּס ערך זה הוא מִינִימוּם מספר תוספות. ההיגיון הוא אינטואיטיבי, אנחנו לא צריכים להוסיף את פלינדרום ורק כאלה שאינם יוצרים את הפלינדרום. כדי למצוא את הפלינדרום הגדול ביותר הזה מהסוף אנחנו לַהֲפוֹך המחרוזת לחשב את DFA.

ה DFA (אוטומט סופי דטרמיניסטי) מוזכר בהקשר של אלגוריתם קנוט מוריס פראט הוא מושג המשמש כדי לעזור למצוא את הקידומת הארוכה ביותר של מחרוזת שהיא גם סיומת ולהפוך את המחרוזת שוב (ובכך להחזיר את המחרוזת המקורית) ולמצוא את המצב הסופי שמייצג את מספר ההתאמות של המחרוזת עם המיתר הנערץ ומכאן שנקבל את תת המחרוזת הגדולה ביותר שהיא פלינדרום מהקצה.

C++
// CPP program for the given approach  // using 2D vector for DFA #include    using namespace std; // Function to build the DFA and precompute the state vector<vector<int>> buildDFA(string& s) {  int n = s.length();    // Number of possible characters (ASCII range)  int c = 256;     // Initialize 2D vector with zeros  vector<vector<int>> dfa(n vector<int>(c 0));   int x = 0;  dfa[0][s[0]] = 1;  // Build the DFA for the given string  for (int i = 1; i < n; i++) {  for (int j = 0; j < c; j++) {  dfa[i][j] = dfa[x][j];  }  dfa[i][s[i]] = i + 1;  x = dfa[x][s[i]];  }  return dfa; } // Function to find the longest overlap // between the string and its reverse int longestOverlap(vector<vector<int>>& dfa string& query) {  int ql = query.length();  int state = 0;  // Traverse through the query to   // find the longest overlap  for (int i = 0; i < ql; i++) {  state = dfa[state][query[i]];  }  return state; } // Function to find the minimum // number of characters to append int minAppends(string s) {    // Reverse the string  string reversedS = s;  reverse(reversedS.begin() reversedS.end());  // Build the DFA for the reversed string  vector<vector<int>> dfa = buildDFA(reversedS);  // Get the longest overlap with the original string  int longestOverlapLength = longestOverlap(dfa s);  // Minimum characters to append   // to make the string a palindrome  return s.length() - longestOverlapLength; } int main() {  string s = 'abede';  cout << minAppends(s) << endl;  return 0; } 
Java
// Java program for the given approach // using 2D array for DFA import java.util.*; class GfG {  // Function to build the DFA and precompute the state  static int[][] buildDFA(String s) {  int n = s.length();  // Number of possible characters (ASCII range)  int c = 256;  // Initialize 2D array with zeros  int[][] dfa = new int[n][c];  int x = 0;  dfa[0][s.charAt(0)] = 1;  // Build the DFA for the given string  for (int i = 1; i < n; i++) {  for (int j = 0; j < c; j++) {  dfa[i][j] = dfa[x][j];  }  dfa[i][s.charAt(i)] = i + 1;  x = dfa[x][s.charAt(i)];  }  return dfa;  }  // Function to find the longest overlap  // between the string and its reverse  static int longestOverlap(int[][] dfa String query) {  int ql = query.length();  int state = 0;  // Traverse through the query to   // find the longest overlap  for (int i = 0; i < ql; i++) {  state = dfa[state][query.charAt(i)];  }  return state;  }  // Function to find the minimum  // number of characters to append  static int minAppends(String s) {    // Reverse the string  String reversedS = new StringBuilder(s).reverse().toString();  // Build the DFA for the reversed string  int[][] dfa = buildDFA(reversedS);  // Get the longest overlap with the original string  int longestOverlapLength = longestOverlap(dfa s);  // Minimum characters to append   // to make the string a palindrome  return s.length() - longestOverlapLength;  }  public static void main(String[] args) {  String s = 'abede';  System.out.println(minAppends(s));  } } 
Python
# Python program for the given approach  # using 2D list for DFA # Function to build the DFA and precompute the state def buildDFA(s): n = len(s) # Number of possible characters (ASCII range) c = 256 # Initialize 2D list with zeros dfa = [[0] * c for _ in range(n)] x = 0 dfa[0][ord(s[0])] = 1 # Build the DFA for the given string for i in range(1 n): for j in range(c): dfa[i][j] = dfa[x][j] dfa[i][ord(s[i])] = i + 1 x = dfa[x][ord(s[i])] return dfa # Function to find the longest overlap # between the string and its reverse def longestOverlap(dfa query): ql = len(query) state = 0 # Traverse through the query to  # find the longest overlap for i in range(ql): state = dfa[state][ord(query[i])] return state # Function to find the minimum # number of characters to append def minAppends(s): # Reverse the string reversedS = s[::-1] # Build the DFA for the reversed string dfa = buildDFA(reversedS) # Get the longest overlap with the # original string longestOverlapLength = longestOverlap(dfa s) # Minimum characters to append  # to make the string a palindrome return len(s) - longestOverlapLength if __name__ == '__main__': s = 'abede' print(minAppends(s)) 
C#
// C# program for the given approach // using 2D array for DFA using System; class GfG {  // Function to build the DFA and precompute the state  static int[] buildDFA(string s) {  int n = s.Length;  // Number of possible characters   // (ASCII range)  int c = 256;  // Initialize 2D array with zeros  int[] dfa = new int[n c];  int x = 0;  dfa[0 s[0]] = 1;  // Build the DFA for the given string  for (int i = 1; i < n; i++) {  for (int j = 0; j < c; j++) {  dfa[i j] = dfa[x j];  }  dfa[i s[i]] = i + 1;  x = dfa[x s[i]];  }  return dfa;  }  // Function to find the longest overlap  // between the string and its reverse  static int longestOverlap(int[] dfa string query) {  int ql = query.Length;  int state = 0;  // Traverse through the query to   // find the longest overlap  for (int i = 0; i < ql; i++) {  state = dfa[state query[i]];  }  return state;  }  // Function to find the minimum  // number of characters to append  static int minAppends(string s) {    // Reverse the string using char array  char[] reversedArray = s.ToCharArray();  Array.Reverse(reversedArray);  string reversedS = new string(reversedArray);  // Build the DFA for the reversed string  int[] dfa = buildDFA(reversedS);  // Get the longest overlap with the original string  int longestOverlapLength = longestOverlap(dfa s);  // Minimum characters to append   // to make the string a palindrome  return s.Length - longestOverlapLength;  }  static void Main() {  string s = 'abede';  Console.WriteLine(minAppends(s));  } } 
JavaScript
// JavaScript program for the given approach // using 2D array for DFA // Function to build the DFA and precompute the state function buildDFA(s) {  let n = s.length;  // Number of possible characters  // (ASCII range)  let c = 256;  // Initialize 2D array with zeros  let dfa = Array.from({ length: n } () => Array(c).fill(0));  let x = 0;  dfa[0][s.charCodeAt(0)] = 1;  // Build the DFA for the given string  for (let i = 1; i < n; i++) {  for (let j = 0; j < c; j++) {  dfa[i][j] = dfa[x][j];  }  dfa[i][s.charCodeAt(i)] = i + 1;  x = dfa[x][s.charCodeAt(i)];  }  return dfa; } // Function to find the longest overlap // between the string and its reverse function longestOverlap(dfa query) {  let ql = query.length;  let state = 0;  // Traverse through the query to   // find the longest overlap  for (let i = 0; i < ql; i++) {  state = dfa[state][query.charCodeAt(i)];  }  return state; } // Function to find the minimum // number of characters to append function minAppends(s) {  // Reverse the string  let reversedS = s.split('').reverse().join('');  // Build the DFA for the reversed string  let dfa = buildDFA(reversedS);  // Get the longest overlap with the original string  let longestOverlapLength = longestOverlap(dfa s);  // Minimum characters to append   // to make the string a palindrome  return s.length - longestOverlapLength; } let s = 'abede'; console.log(minAppends(s)); 

תְפוּקָה
2 

  מאמר קשור: 

  • תכנות דינמי | סט 28 (מינימום כניסות ליצירת פלינדרום)
צור חידון