给定一个字符串S,我们需要编写一个程序来检查是否可以通过执行以下任何操作任意次数来构造给定的字符串S。在每个步骤中,我们可以:
- 在字符串末尾添加任何字符。
- 或者,将字符串附加到字符串本身。
上述步骤可以应用任意次数。我们需要编写一个程序来打印形成字符串所需的最少步骤。
例子:
Input : aaaaaaaa
Output : 4
Explanation: move 1: add 'a' to form "a"
move 2: add 'a' to form "aa"
move 3: append "aa" to form "aaaa"
move 4: append "aaaa" to form "aaaaaaaa"
Input: aaaaaa
Output: 4
Explanation: move 1: add 'a' to form "a"
move 2: add 'a' to form "aa"
move 3: add 'a' to form "aaa"
move 4: append "aaa" to form "aaaaaa"
Input: abcabca
Output: 5
解决这个问题的想法是使用动态规划来计算最小移动次数。创建一个大小为 n 的名为dp的数组,其中 n 是输入字符串的长度。 dp[i] 存储生成子串 (0…i) 所需的最小移动次数。根据问题,有两种可能的移动:
- dp[i] = min(dp[i], dp[i-1] + 1)表示添加字符。
- dp[i*2+1] = min(dp[i]+1, dp[i*2+1]) ,如果 s[0…i]==s[i+1..i,则追加字符串*2+1]
答案将存储在dp[n-1] 中,因为我们需要按索引形成字符串(0..n-1)。
下面是上述想法的实现:
C++
// CPP program to print the // Minimal moves to form a string // by appending string and adding characters #include
using namespace std; // function to return the minimal number of moves int minimalSteps(string s, int n) { int dp[n]; // initializing dp[i] to INT_MAX for (int i = 0; i < n; i++) dp[i] = INT_MAX; // initialize both strings to null string s1 = "", s2 = ""; // base case dp[0] = 1; s1 += s[0]; for (int i = 1; i < n; i++) { s1 += s[i]; // check if it can be appended s2 = s.substr(i + 1, i + 1); // addition of character takes one step dp[i] = min(dp[i], dp[i - 1] + 1); // appending takes 1 step, and we directly // reach index i*2+1 after appending // so the number of steps is stord in i*2+1 if (s1 == s2) dp[i * 2 + 1] = min(dp[i] + 1, dp[i * 2 + 1]); } return dp[n - 1]; } // Driver Code int main() { string s = "aaaaaaaa"; int n = s.length(); // function call to return minimal number of moves cout << minimalSteps(s, n); return 0; }
Java
// Java program to print the // Minimal moves to form a string // by appending string and adding characters import java.util.*; class GFG { // function to return the minimal number of moves static int minimalSteps(String s, int n) { int []dp = new int[n]; // initializing dp[i] to INT_MAX for (int i = 0; i < n; i++) dp[i] = Integer.MAX_VALUE; // initialize both strings to null String s1 = "", s2 = ""; // base case dp[0] = 1; s1 += s.charAt(0); for (int i = 1; i < n; i++) { s1 += s.charAt(i); // check if it can be appended s2 = s.substring(i + 1, i + 1); // addition of character takes one step dp[i] = Math.min(dp[i], dp[i - 1] + 1); // appending takes 1 step, and we directly // reach index i*2+1 after appending // so the number of steps is stord in i*2+1 if (s1 == s2) dp[i * 2 + 1] = Math.min(dp[i] + 1, dp[i * 2 + 1]); } return dp[n - 1]; } // Driver Code public static void main(String args[]) { String s = "aaaaaaaa"; int n = s.length(); // function call to return minimal number of moves System.out.println(minimalSteps(s, n)/2); } } // This code is contributed by // Shashank_Sharma
Python3
# Python program to print the # Minimal moves to form a string # by appending string and adding characters INT_MAX = 100000000 # function to return the # minimal number of moves def minimalSteps(s, n): dp = [INT_MAX for i in range(n)] # initialize both strings to null s1 = "" s2 = "" # base case dp[0] = 1 s1 += s[0] for i in range(1, n): s1 += s[i] # check if it can be appended s2 = s[i + 1: i + 1 + i + 1] # addition of character # takes one step dp[i] = min(dp[i], dp[i - 1] + 1) # appending takes 1 step, and # we directly reach index i*2+1 # after appending so the number # of steps is stord in i*2+1 if (s1 == s2): dp[i * 2 + 1] = min(dp[i] + 1, dp[i * 2 + 1]) return dp[n - 1] # Driver Code s = "aaaaaaaa" n =len(s) # function call to return # minimal number of moves print( minimalSteps(s, n) ) # This code is contributed # by sahilshelangia
C#
// C# program to print the // Minimal moves to form a string // by appending string and adding characters using System; class GFG { // function to return the minimal number of moves static int minimalSteps(String s, int n) { int []dp = new int[n]; // initializing dp[i] to INT_MAX for (int i = 0; i < n; i++) dp[i] = int.MaxValue; // initialize both strings to null String s1 = "", s2 = ""; // base case dp[0] = 1; s1 += s[0]; for (int i = 1; i < n; i++) { s1 += s[i]; // check if it can be appended s2 = s.Substring(i , 1); // addition of character takes one step dp[i] = Math.Min(dp[i], dp[i - 1] + 1); // appending takes 1 step, and we directly // reach index i*2+1 after appending // so the number of steps is stord in i*2+1 if (s1 == s2) dp[i * 2 + 1] = Math.Min(dp[i] + 1, dp[i * 2 + 1]); } return dp[n - 1]; } // Driver Code public static void Main(String []args) { String s = "aaaaaaaa"; int n = s.Length; // function call to return minimal number of moves Console.Write(minimalSteps(s, n)/2); } } // This code has been contributed by 29AjayKumar
PHP
输出:
4
时间复杂度: O(n 2 ),其中 n 是输入字符串的长度。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。