给定一个字符串S和一个分别为长度N和M的字符串arr []的数组,任务是通过交换最小字符数来从给定数组到字符串S中查找字符串。如果没有字符串可以转换为S ,则打印-1。
例子:
Input: S = “abc”, arr[] = {“acb”, “xyz”}
Output: acb
Explanation:
The string “acb” can be converted to “abc” by swapping 1 pair of characters “acb” -> “abc“.
The string”xyz” cannot be converted to “abc”.
Input: S = “abc”, arr[] = {“ab”, “xy”, “cb”}
Output: -1
方法:可以通过从给定的字符串数组中搜索S的字母符号来解决问题,然后针对每个这样的字符串,找到将字符串转换为S所需的最少字符交换数。
请按照以下步骤解决问题:
- 遍历字符串数组和每个数组中存在的字符串,检查它是否是S的或不是字谜。
- 如果找不到这样的字符串,则打印-1 。
- 否则,找到交换的最小数量要求当前字符串转换为S,通过遍历当前字符串中的字符,比如S1。
- 将字符的位置存储在26个列表中的S1中。对于S1中的每个字符,将其索引附加到其对应的列表中,即列表0存储字符‘a’的所有位置。同样,列表1存储所有‘b’的位置,依此类推。
- 字符串S1的完整遍历之后,迭代字符串S在反向与每个字符的字符,说S [j]时,从列表,比如温度的给定阵列得到其相应的指数。
- 现在,最佳的方法是将温度最后一个索引处的字符移动到索引j处。这是最佳选择,因为:
- 字符在每一步中都在移动。因此,没有浪费任何行动。
- temp的最后一个索引将比其他索引更接近j ,因为该字符串将反向迭代。
- 为了进行优化,如果有任何交换,可以使用Fenwick树确定字符在S1中的修改位置。
插图:
Suppose, S = “abca”, S1 = “cbaa”
Below is the list generated for S1:
List for ‘a’ = {2, 3}
List for ‘b’ = {1}
List for ‘c’ = {0}
Iterate over the characters of S, in reverse, by initializing minMoves with 0.
- S = “abca”, i = 3
Remove last index from list corresponding to ‘a’, i.e. 3.
Search the Fenwick Tree to check if there are any indices to the left of this index in the Fenwick Tree or not.
Since the tree is empty now, no need to shift this index.
Add index 3 to the Fenwick Tree.
minMoves += (i – index) = (3 – 3). Therefore, minMoves = 0 - S = “abca”, i = 2
Remove the last index from list corresponding to ‘c’, i.e. 0.
Search the Fenwick Tree to check if there are any indices to the left of this index in the Fenwick Tree or not.
Since the only index in the tree is 3, and it is to the right of 0, no need to shift this index.
Add index 0 to the Fenwick Tree.
minMoves += (i – index) = (2 – 0). Therefore, minMoves = 2 - S = “abca”, i = 1
Remove last index from list corresponding to ‘b’, i.e. 1.
Search the Fenwick Tree to check if there are any indices to the left of this index in the Fenwick Tree or not.
The count obtained is 1, i.e. there was one character to the left of index 1, which is now, towards it’s right.
Add index 1 to the Fenwick Tree.
new index = 1 – leftShit = 1 – 1 = 0
minMoves += (i – new index) = 1 – 0 = 3 - S = “abca”, i= 0
Remove last index from list corresponding to ‘a’, i.e. 2.
Search the Fenwick Tree to check if there are any indices to the left of this index in the Fenwick tree or not.
The count obtained is 2, i.e. there were two characters to the left of index 2, which is now, towards its right.
Add index 2 to the Fenwick Tree.
new index = 2 – leftShit = 2 – 2 = 0
minMoves+= (i-new index) = 0 – 0 = 3
下面是上述方法的实现:
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)