给定长度为N的两个字符串S和T ,它们由小写字母组成,它们彼此置换,因此任务是打印最小数量的操作,以将S转换为T。在一个操作中,挑字符串S中的任何字符,要么将其移动到字符串S的开始或结束。
例子:
Input: S = “abcde”, T = “edacb”
Output: 3
Explanation:
We can convert S to T in 3 moves:
1. move ‘d’ to start: “dabce”
2. move ‘e’ to start: “edabc”
3. move ‘b’ to end: “edacb”
Input: S = “dcdb”, T = “ddbc”
Output: 1
Explanation:
Move ‘c’ to end
天真的方法:天真的方法是尝试交换字符的所有可能性。可以将某个字符放在前面,后面或保留在相同位置。以上三个操作可以使用递归来解决 并在所有步骤之后打印所需的最少步骤数。
时间复杂度: O(3 N ),其中N是给定字符串的长度。
辅助空间: O(1)
高效的方法:为了优化上述方法,我们的想法是观察到在移动字符串S的字符后,未更改的字符会聚在一起形成T中的连续子字符串。因此,如果我们可以最大化此子序列的长度,则将字符串S转换为T的操作数为:
N – length of the longest contiguous substring of T that is a subsequence of S
因此,要找到作为字符串S的子序列的T的最长连续子字符串的长度,请找到S和T的最长的公共子序列。令dp [] []存储T的最长连续子字符串的长度,它是字符串S ,的子序列。现在dp [i] [j]将存储T [0,…,j]的最长后缀的长度,它也是S [0,…,i]的子序列。递归关系由下式给出:
- 如果i大于0,则dp [i] [j] = max(dp [i-1] [j],dp [i] [j])。
- 如果S [i]等于T [i],则dp [i] [j] = 1 + dp [i-1] [j-1]。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
int dp[1010][1010];
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert string s to t
int solve(string s, string t)
{
int n = s.size();
// r = maximum value over all
// dp[i][j] computed so far
int r = 0;
// dp[i][j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dp[i][j] = 0;
if (i > 0) {
dp[i][j] = max(dp[i - 1][j],
dp[i][j]);
}
if (s[i] == t[j]) {
int ans = 1;
if (i > 0 && j > 0) {
ans = 1 + dp[i - 1][j - 1];
}
// Update the maximum length
dp[i][j] = max(dp[i][j], ans);
r = max(r, dp[i][j]);
}
}
}
// Return the resulting length
return (n - r);
}
// Driver Code
int main()
{
// Given string s, t
string s = "abcde";
string t = "edacb";
// Function Call
cout << solve(s, t);
return 0;
}
Java
// Java program for the above approach
class GFG{
static int[][] dp = new int[1010][1010];
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert String s to t
static int solve(String s, String t)
{
int n = s.length();
// r = maximum value over all
// dp[i][j] computed so far
int r = 0;
// dp[i][j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
dp[i][j] = 0;
if (i > 0)
{
dp[i][j] = Math.max(dp[i - 1][j],
dp[i][j]);
}
if (s.charAt(i) == t.charAt(j))
{
int ans = 1;
if (i > 0 && j > 0)
{
ans = 1 + dp[i - 1][j - 1];
}
// Update the maximum length
dp[i][j] = Math.max(dp[i][j], ans);
r = Math.max(r, dp[i][j]);
}
}
}
// Return the resulting length
return (n - r);
}
// Driver Code
public static void main(String[] args)
{
// Given String s, t
String s = "abcde";
String t = "edacb";
// Function Call
System.out.print(solve(s, t));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
dp = [[0] * 1010] * 1010
# Function that finds the minimum number
# of steps to find the minimum characters
# must be moved to convert string s to t
def solve(s, t):
n = len(s)
# r = maximum value over all
# dp[i][j] computed so far
r = 0
# dp[i][j] stores the longest
# contiguous suffix of T[0..j]
# that is subsequence of S[0..i]
for j in range(0, n):
for i in range(0, n):
dp[i][j] = 0
if (i > 0):
dp[i][j] = max(dp[i - 1][j],
dp[i][j])
if (s[i] == t[j]):
ans = 1
if (i > 0 and j > 0):
ans = 1 + dp[i - 1][j - 1]
# Update the maximum length
dp[i][j] = max(dp[i][j], ans)
r = max(r, dp[i][j])
# Return the resulting length
return (n - r)
# Driver Code
# Given string s, t
s = "abcde"
t = "edacb"
# Function call
print(solve(s, t))
# This code is contributed by code_hunt
C#
// C# program for the above approach
using System;
class GFG{
static int[, ] dp = new int[1010, 1010];
// Function that finds the minimum number
// of steps to find the minimum characters
// must be moved to convert String s to t
static int solve(String s, String t)
{
int n = s.Length;
// r = maximum value over all
// dp[i, j] computed so far
int r = 0;
// dp[i, j] stores the longest
// contiguous suffix of T[0..j]
// that is subsequence of S[0..i]
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
dp[i, j] = 0;
if (i > 0)
{
dp[i, j] = Math.Max(dp[i - 1, j],
dp[i, j]);
}
if (s[i] == t[j])
{
int ans = 1;
if (i > 0 && j > 0)
{
ans = 1 + dp[i - 1, j - 1];
}
// Update the maximum length
dp[i, j] = Math.Max(dp[i, j], ans);
r = Math.Max(r, dp[i, j]);
}
}
}
// Return the resulting length
return (n - r);
}
// Driver Code
public static void Main(String[] args)
{
// Given String s, t
String s = "abcde";
String t = "edacb";
// Function Call
Console.Write(solve(s, t));
}
}
// This code is contributed by shikhasingrajput
3
时间复杂度: O(N 2 ),其中N是给定字符串的长度
辅助空间: O(N 2 )
注意:上面的幼稚方法对于较小的字符串是有效的,而上面的有效方法对于较大的字符串是有效的。