📌  相关文章
📜  发现从一个数组,可以被转换成一个字符串S与互换的最小数目的字符串

📅  最后修改于: 2021-05-13 23:14:17             🧑  作者: Mango

给定一个字符串S和一个分别为长度NM的字符串arr []的数组,任务是通过交换最小字符数来从给定数组到字符串S中查找字符串。如果没有字符串可以转换为S ,则打印-1。

例子:

方法:可以通过从给定的字符串数组中搜索S的字母符号来解决问题,然后针对每个这样的字符串,找到将字符串转换为S所需的最少字符交换数。

请按照以下步骤解决问题:

  • 遍历字符串数组和每个数组中存在的字符串,检查它是否是S的或不是字谜。
  • 如果找不到这样的字符串,则打印-1
  • 否则,找到交换的最小数量要求当前字符串转换为S,通过遍历当前字符串中的字符,比如S1。
  • 将字符的位置存储在26个列表中的S1中。对于S1中的每个字符,将其索引附加到其对应的列表中,即列表0存储字符‘a’的所有位置。同样,列表1存储所有‘b’的位置,依此类推。
  • 字符串S1的完整遍历之后,迭代字符串S在反向与每个字符的字符,说S [j]时,从列表,比如温度的给定阵列得到其相应的指数。
  • 现在,最佳的方法是将温度最后一个索引处的字符移动到索引j处。这是最佳选择,因为:
    • 字符在每一步中都在移动。因此,没有浪费任何行动。
    • temp的最后一个索引将比其他索引更接近j ,因为该字符串将反向迭代。
    • 为了进行优化,如果有任何交换,可以使用Fenwick树确定字符在S1中的修改位置。

插图:

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Fucntion to check is two
// strings are anagrams
bool checkIsAnagram(vector charCountS,
                    vector charCountS1)
{
    for(int i = 0; i < 26; i++)
    {
        if (charCountS[i] != charCountS1[i])
            return false;
    }
    return true;
}
 
// Function to return the frequency of
// characters in the array of strings
vector getCharCount(string S)
{
    vector charCount(26, 0);
 
    for(char i:S)
        charCount[i - 'a']++;
 
    return charCount;
}
 
// Function to return the count of
// indices to the left of this index
int get(vector &fenwickTree, int index)
{
    int leftShift = 0;
    leftShift += fenwickTree[index];
 
    while (index > 0)
    {
        index -= (-index) & index;
        leftShift += fenwickTree[index];
    }
    return leftShift;
}
 
// Update function of Fenwick Tree
void update(vector &fenwickTree,
                   int index)
{
    while (index < fenwickTree.size())
    {
        fenwickTree[index]++;
        index += (-index) & index;
    }
}
 
// Function to get all positions of
// characters present in the strng S1
vector> getPositions(string S)
{
     
    //@SuppressWarnings("unchecked")
    vector> charPositions(26);
 
    for(int i = 0; i < S.size(); i++)
        charPositions[i - 'a'].push_back(i);
 
    return charPositions;
}
 
// Function to return the minimum number
// of swaps required to convert S1 to S
int findMinMoves(string S, string S1)
{
     
    // cout<<"run\n";
    // Stores number of swaps
    int minMoves = 0;
     
    // Initialize Fenwick Tree
    vector fenwickTree(S.size() + 1);
     
    // Get all positions of characters
    // present in the string S1
    vector charPositions[26];
    int j = 0;
    for(char i:S1)
    {
        charPositions[i-'a'].push_back(j);
        j++;
    }
     
    // cout<= 0; i--)
    {
         
        // Get the list corresponding
        // to character S[i]
        vector temp = charPositions[S[i] - 'a'];
         
        // Size of the list
        int size = temp.size() - 1;
         
        // Get and remove last
        // indices from the list
        int index = temp[size] + 1;
        charPositions[S[i] - 'a'].pop_back();
         
        //temp.pop_back();
         
        // Count of indices to
        // the left of this index
        int leftShift = get(fenwickTree, index);
         
        // Update Fenwick T ree
        update(fenwickTree, index);
         
        // Shift the index to it's left
        index -= leftShift;
         
        // Update moves
        minMoves += abs(i - index + 1);
    }
     
    // Return moves
    return minMoves;
}
 
// Function to find anagram of S
// requiring minimum number of swaps
string getBeststring(string S, vector group)
{
     
    // Initialize variables
    bool isAnagram = false;
    string beststring ="";
    int minMoves = INT_MAX;
 
    // Count frequency of characters in S
    vector charCountS = getCharCount(S);
 
    // Traverse the array of strings
    for(string S1 : group)
    {
         
        // Count frequency of characters in S1
        vector charCountS1 = getCharCount(S1);
 
        // cout< arr = { "cbdaca",
                           "abcacd",
                           "abcdef" };
 
    string beststring = getBeststring(S, arr);
 
    // Print answer
    cout << (beststring) << endl;
}
 
// This code is contributed by mohit kumar 29


Java
// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to find anagram of S
    // requiring minimum number of swaps
    static String getBestString(String S,
                                List group)
    {
        // Initialize variables
        boolean isAnagram = false;
        String bestString = null;
        int minMoves = Integer.MAX_VALUE;
 
        // Count frequency of characters in S
        int[] charCountS = getCharCount(S);
 
        // Traverse the array of strings
        for (String S1 : group) {
 
            // Count frequency of characters in S1
            int[] charCountS1 = getCharCount(S1);
 
            // Check if S1 is anagram of S
            boolean anagram
                = checkIsAnagram(charCountS,
                                 charCountS1);
 
            // If not an anagram of S
            if (!anagram)
                continue;
 
            isAnagram = true;
 
            // Count swaps required
            // to convert S to S1
            int moves = findMinMoves(S, S1);
 
            // Count minimum number of swaps
            if (moves < minMoves) {
                minMoves = moves;
                bestString = S1;
            }
        }
 
        // If no anagram is found, print -1
        return (isAnagram) ? bestString : "-1";
    }
 
    // Function to return the minimum number
    // of swaps required to convert S1 to S
    static int findMinMoves(String S, String S1)
    {
 
        // Stores number of swaps
        int minMoves = 0;
 
        // Initialize Fenwick Tree
        int[] fenwickTree = new int[S.length() + 1];
 
        // Get all positions of characters
        // present in the string S1
        List > charPositions
            = getPositions(S1);
 
        // Traverse the given string in reverse
        for (int i = S.length() - 1; i >= 0; i--) {
 
            // Get the list corresponding
            // to character S[i]
            List temp
                = charPositions.get(
                    S.charAt(i) - 'a');
 
            // Size of the list
            int size = temp.size() - 1;
 
            // Get and remove last
            // indices from the list
            int index = temp.remove(size) + 1;
 
            // Count of indices to
            // the left of this index
            int leftShift = get(
                fenwickTree, index);
 
            // Update Fenwick T ree
            update(fenwickTree, index);
 
            // Shift the index to it's left
            index -= leftShift;
 
            // Update moves
            minMoves += Math.abs(i - index + 1);
        }
 
        // Return moves
        return minMoves;
    }
 
    // Function to get all positions of
    // characters present in the strng S1
    static List > getPositions(
        String S)
    {
        @SuppressWarnings("unchecked")
        List > charPositions
            = new ArrayList();
 
        for (int i = 0; i < 26; i++)
            charPositions.add(
                new ArrayList());
 
        for (int i = 0; i < S.length(); i++)
            charPositions.get(
                             S.charAt(i) - 'a')
                .add(i);
 
        return charPositions;
    }
 
    // Update function of Fenwick Tree
    static void update(int[] fenwickTree,
                       int index)
    {
        while (index < fenwickTree.length) {
            fenwickTree[index]++;
            index += (-index) & index;
        }
    }
 
    // Function to return the count of
    // indices to the left of this index
    static int get(int[] fenwickTree, int index)
    {
        int leftShift = 0;
        leftShift += fenwickTree[index];
 
        while (index > 0) {
            index -= (-index) & index;
            leftShift += fenwickTree[index];
        }
        return leftShift;
    }
 
    // Function to return the frequency of
    // characters in the array of strings
    static int[] getCharCount(String S)
    {
        int[] charCount = new int[26];
 
        for (int i = 0; i < S.length(); i++)
            charCount[S.charAt(i) - 'a']++;
 
        return charCount;
    }
 
    // Fucntion to check is two
    // strings are anagrams
    static boolean checkIsAnagram(
        int[] charCountS,
        int[] charCountS1)
    {
 
        for (int i = 0; i < 26; i++) {
            if (charCountS[i] != charCountS1[i])
                return false;
        }
 
        return true;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
 
        // Given string
        String S = "abcdac";
 
        // Given array of strings
        String arr[] = { "cbdaca",
                         "abcacd",
                         "abcdef" };
 
        String bestString
            = getBestString(S, Arrays.asList(arr));
 
        // Print answer
        System.out.println(bestString);
    }
}


输出:
abcacd

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