📌  相关文章
📜  通过将字符移动到前端或末尾来将给定字符串转换为另一个字符串的最少操作

📅  最后修改于: 2021-09-17 07:45:19             🧑  作者: Mango

给定两个长度为N 的字符串ST由小写字母组成,它们是彼此的排列,任务是打印将S转换为T的最少操作数。在一个操作中,挑字符串S中的任何字符,要么将其移动到字符串S的开始或结束。

例子:

朴素的方法:朴素的方法是尝试交换字符的所有可能性。可以将某个字符放在前面、后面,也可以将其保留在同一位置。以上三个操作可以使用递归解决 并在所有步骤之后打印所需的最少步骤数。
时间复杂度: O(3 N ),其中 N 是给定字符串的长度。
辅助空间: O(1)

高效的方法:优化上述方法,其思想是观察在移动字符串S的字符后,未更改的字符聚集在一起形成T 中的连续子字符串。所以,如果我们可以最大化这个子序列的长度,那么将字符串S转换为T的操作次数是:

因此,要找到作为字符串S 的子序列的T的最长连续子串的长度,请找到ST的最长公共子序列。让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


Javascript


输出:
3

时间复杂度: O(N 2 ),其中 N 是给定字符串的长度
辅助空间: O(N 2 )

注意:上述简单的方法对于较小的字符串是有效的,而上述有效的方法对于较大的字符串是有效的。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程