📌  相关文章
📜  通过最小字符替换子序列的最少次数将给定字符串转换为另一个字符串

📅  最后修改于: 2021-10-27 16:43:46             🧑  作者: Mango

给定两个字符串AB ,任务是计算将字符串A转换为B所需的最少操作数。在一个操作中,从字符串A 中选择一个子序列并将该子序列的每个字符转换为其中存在的最小字符。如果无法转换,则打印“-1”

例子:

方法:该方法是基于这样的想法,如果在索引中的任何字符,我字符串A的小于字符的字符串B的I指数,那么它是不可能改变A到B,因为改变字符一个字符比自己小不被允许。以下是步骤:

  1. 初始化两个向量数组convCharstr1array ,大小为 26。这些数组的每个索引对应一个字符。
  2. convChari索引包含字符串A的指数应该转换为i字母和str1array包含字符串A的所有字符的索引
  3. 初始化一个HashMap convertMap指示特定字符,其中字符索引i字符串A的应转换到。
  4. 同时迭代两个字符串,可能会出现三种情况:
    • 如果字符串A 的i字符小于字符串B 的i字符,则不可能将A更改为B 。因此,打印“-1”
    • 如果当前索引上的两个字符相同,则不需要更改。
    • 否则,插入的索引这个索引i在convChar阵列对应于第i字符串B字符和与密钥值作为我插入i的字符值在HashMap中convertMap在字符串B字符。
  5. 初始化计算所需最少操作的变量ret和用于存储操作集的向量retV
  6. 现在以相反的顺序迭代所有字母。在每次迭代中执行以下步骤:
    • 检查每个字母表,是否至少有一个索引应转换为当前字母表。
    • ret增加 1 以计算所需的步骤数。设v是应该转换为当前字母表的索引向量,索引为 i , v1是包含字符串A 的所有索引的向量。那么可能会出现两种情况:
      1. 如果v1没有元素,则当前字母表不存在于字符串A 中。因此,不可能将 A 更改为 B。
      2. 否则,继续下一步。
    • 迭代向量v1 的每个索引j 。在此迭代中,搜索要包含在集合S 中的最小索引。
      1. 如果convertMap 中存在向量 v1 的j字母,则表示该字母已经或将在操作中转换为另一个字符。如果它已在之前的操作之一中被转换,则继续v1 的下一次迭代。
      2. 否则在集合中添加这个索引。然后跳出循环
    • 如果在向量v1 中找不到任何这样的索引j ,则不可能将字符串A转换为B 。因此打印“-1”

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to return the minimum number
// of operation
void transformString(string str1,
                    string str2)
{
    // Storing data
    int N = str1.length();
 
    vector convChar[26];
    vector str1array[26];
 
    // Initialize both arrays
    for (int i = 0; i < 26; i++) {
        vector v;
        convChar[i] = v;
        str1array[i] = v;
    }
 
    // Stores the index of character
    map convertMap;
 
    // Filling str1array, convChar
    // and hashmap convertMap.
    for (int i = 0; i < N; i++) {
        str1array[str1[i] - 'a'].push_back(i);
    }
 
    for (int i = 0; i < N; i++) {
 
        // Not possible to convert
        if (str1[i] < str2[i]) {
            cout << -1 << endl;
            return;
        }
        else if (str1[i] == str2[i])
            continue;
        else {
            convChar[str2[i] - 'a'].push_back(i);
            convertMap[i] = str2[i];
        }
    }
 
    // Calculate result
    // Initializing return values
    int ret = 0;
    vector > retv;
 
    // Iterating the character from
    // the end
    for (int i = 25; i >= 0; i--) {
 
        vector v = convChar[i];
 
        if (v.size() == 0)
            continue;
 
        // Increment the number of
        // operations
        ret++;
        vector v1 = str1array[i];
 
        // Not possible to convert
        if (v1.size() == 0) {
            cout << -1 << endl;
            return;
        }
 
        // to check whether the final
        // element has been added
        // in set S or not.
        bool isScompleted = false;
 
        for (int j = 0; j < v1.size(); j++) {
 
            // Check if v1[j] is present
            // in hashmap or not
            if (convertMap.find(v1[j])
                != convertMap.end()) {
 
                char a = convertMap[v1[j]];
 
                // Already converted then
                // then continue
                if (a > i + 'a')
                    continue;
                else {
                    v.push_back(v1[j]);
                    isScompleted = true;
                    retv.push_back(v);
                    break;
                }
            }
            else {
                v.push_back(v1[j]);
                isScompleted = true;
                retv.push_back(v);
                break;
            }
        }
 
        // Not possible to convert
        if (!isScompleted) {
            cout << -1 << endl;
            return;
        }
    }
 
    // Print the result
    cout << ret << endl;
}
 
// Driver Code
int main()
{
    // Given strings
    string A = "abcab";
    string B = "aabab";
 
    // Function Call
    transformString(A, B);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
 
class GFG{
 
// Function to return the minimum number
// of operation
static void transformString(String str1,
                            String str2)
{
    // Storing data
    int N = str1.length();
    ArrayList<
    ArrayList> convChar = new ArrayList<>();
    ArrayList<
    ArrayList> str1array = new ArrayList<>();
 
    // Initialize both arrays
    for(int i = 0; i < 26; i++)
    {
        convChar.add(new ArrayList<>());
        str1array.add(new ArrayList<>());
    }
 
    // Stores the index of character
    Map convertMap = new HashMap<>();
 
    // Filling str1array, convChar
    // and hashmap convertMap.
    for(int i = 0; i < N; i++)
    {
        str1array.get(str1.charAt(i) - 'a').add(i);
    }
 
    for(int i = 0; i < N; i++)
    {
         
        // Not possible to convert
        if (str1.charAt(i) < str2.charAt(i))
        {
            System.out.println(-1);
            return;
        }
        else if (str1.charAt(i) == str2.charAt(i))
            continue;
        else
        {
            convChar.get(str2.charAt(i) - 'a').add(i);
            convertMap.put(i,str2.charAt(i));
        }
    }
 
    // Calculate result
    // Initializing return values
    int ret = 0;
    ArrayList<
    ArrayList> retv = new ArrayList<>();
 
    // Iterating the character from
    // the end
    for(int i = 25; i >= 0; i--)
    {
        ArrayList v = convChar.get(i);
 
        if (v.size() == 0)
            continue;
 
        // Increment the number of
        // operations
        ret++;
        ArrayList v1 = str1array.get(i);
 
        // Not possible to convert
        if (v1.size() == 0)
        {
            System.out.println(-1);
            return;
        }
 
        // To check whether the final
        // element has been added
        // in set S or not.
        boolean isScompleted = false;
 
        for(int j = 0; j < v1.size(); j++)
        {
             
            // Check if v1[j] is present
            // in hashmap or not
            if (convertMap.containsKey(v1.get(j)))
            {
                char a = convertMap.get(v1.get(j));
 
                // Already converted then
                // then continue
                if (a > i + 'a')
                    continue;
                else
                {
                    v.add(v1.get(j));
                    isScompleted = true;
                    retv.add(v);
                    break;
                }
            }
            else
            {
                v.add(v1.get(j));
                isScompleted = true;
                retv.add(v);
                break;
            }
        }
 
        // Not possible to convert
        if (!isScompleted)
        {
            System.out.println(-1);
            return;
        }
    }
 
    // Print the result
    System.out.println(ret);
}
 
// Driver Code
public static void main (String[] args)
{
     
    // Given strings
    String A = "abcab";
    String B = "aabab";
     
    // Function call
    transformString(A, B);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
 
# Function to return the minimum number
# of operation
def transformString(str1, str2):
     
    # Storing data
    N = len(str1)
    convChar = []
    str1array = []
     
    # Initialize both arrays
    for i in range(26):
        convChar.append([])
        str1array.append([])
         
    # Stores the index of character
    convertMap = {}
     
    # Filling str1array, convChar
    # and hashmap convertMap.
    for i in range(N):
        str1array[ord(str1[i]) -
                  ord('a')].append(i)
         
    for i in range(N):
         
        # Not possible to convert
        if (str1[i] < str2[i]):
            print(-1)
            return
        elif (str1[i] == str2[i]):
            continue
        else:
            convChar[ord(str2[i]) -
                     ord('a')].append(i)
            convertMap[i] = str2[i]
     
    # Calculate result
    # Initializing return values
    ret = 0
    retv = []
     
    # Iterating the character from
    # the end
    for i in range(25, -1, -1):
        v = convChar[i]
         
        if (len(v) == 0):
            continue
         
        # Increment the number of
        # operations
        ret += 1;
        v1 = str1array[i]
         
        # Not possible to convert
        if (len(v1) == 0):
            print(-1)
            return
         
        # To check whether the final
        # element has been added
        # in set S or not.
        isScompleted = False
         
        for j in range(len(v1)):
             
            # Check if v1[j] is present
            # in hashmap or not
            if (v1[j] in convertMap):
                a = v1[j]
                 
                # Already converted then
                # then continue
                if (a > i + ord('a')):
                    continue
                else:
                    v.append(v1[j])
                    isScompleted = True
                    retv.append(v)
                    break
            else:
                v.append(v1[j])
                isScompleted = True
                retv.append(v)
                break
         
        # Not possible to convert
        if (isScompleted == False):
            print(-1)
            return
     
    # Print the result
    print(ret)
             
# Driver Code
A = "abcab"
B = "aabab"
 
# Function call
transformString(A, B)
 
# This code is contributed by dadi madhav


C#
// C# program for the above approach 
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to return the minimum number 
// of operation 
static void transformString(string str1, string str2) 
{
     
    // Storing data 
    int N = str1.Length; 
    List> convChar = new List>(); 
    List> str1array = new List>(); 
   
    // Initialize both arrays 
    for(int i = 0; i < 26; i++) 
    { 
        convChar.Add(new List()); 
        str1array.Add(new List()); 
    } 
   
    // Stores the index of character 
    Dictionary convertMap = new Dictionary(); 
   
    // Filling str1array, convChar 
    // and hashmap convertMap. 
    for(int i = 0; i < N; i++) 
    { 
        str1array[str1[i] - 'a'].Add(i); 
    } 
   
    for(int i = 0; i < N; i++) 
    { 
         
        // Not possible to convert 
        if (str1[i] < str2[i]) 
        { 
            Console.WriteLine(-1); 
            return; 
        } 
        else if (str1[i] == str2[i]) 
            continue; 
        else
        { 
            convChar[str2[i] - 'a'].Add(i); 
            convertMap[i] = str2[i]; 
        } 
    } 
   
    // Calculate result 
    // Initializing return values 
    int ret = 0; 
    List> retv = new List>(); 
   
    // Iterating the character from 
    // the end 
    for(int i = 25; i >= 0; i--) 
    { 
        List v = convChar[i]; 
   
        if (v.Count == 0) 
            continue; 
   
        // Increment the number of 
        // operations 
        ret++; 
        List v1 = str1array[i]; 
   
        // Not possible to convert 
        if (v1.Count == 0) 
        { 
            Console.WriteLine(-1); 
            return; 
        } 
   
        // To check whether the final 
        // element has been added 
        // in set S or not. 
        bool isScompleted = false; 
   
        for(int j = 0; j < v1.Count; j++) 
        { 
             
            // Check if v1[j] is present 
            // in hashmap or not 
            if (convertMap.ContainsKey(v1[j])) 
            { 
                char a = convertMap[v1[j]]; 
   
                // Already converted then 
                // then continue 
                if (a > i + 'a') 
                    continue; 
                else
                { 
                    v.Add(v1[j]); 
                    isScompleted = true; 
                    retv.Add(v); 
                    break; 
                } 
            } 
            else
            { 
                v.Add(v1[j]); 
                isScompleted = true; 
                retv.Add(v); 
                break; 
            } 
        } 
   
        // Not possible to convert 
        if (!isScompleted) 
        { 
            Console.WriteLine(-1); 
            return; 
        } 
    } 
   
    // Print the result 
    Console.WriteLine(ret); 
}
 
// Driver code
static void Main()
{
    // Given strings 
    string A = "abcab"; 
    string B = "aabab"; 
       
    // Function call 
    transformString(A, B);
}
}
 
// This code is contributed by divyesh072019


输出:
2

时间复杂度: O(N)
辅助空间: O(N)

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