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

📅  最后修改于: 2021-05-14 08:16:35             🧑  作者: Mango

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

例子:

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

  1. 初始化两个大小为26的向量convCharstr1array数组。这些数组的每个索引对应于一个字符。
  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. 如果向量v1的j字母存在于convertMap中,则意味着该字母已被转换或将在操作中转换为另一个字符。如果已通过以前的操作之一进行了转换,请继续进行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)