给定的字符串S和字符串数组的常用3 [分别]的长度N和M,任务是通过交换字符的最小数目来找到从给定的阵列到字符串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。
- 将S1中字符的位置存储在26 个列表中。对于S1 中的每个字符,将其索引附加到其对应的列表中,即列表 0存储字符‘a’ 的所有位置。同样,列表 1存储‘b’ 的所有位置,依此类推。
- 字符串S1的完整遍历之后,迭代字符串S在反向与每个字符的字符,说S [j]时,从列表,比如温度的给定阵列得到其相应的指数。
- 现在,最佳移动是将temp 中最后一个索引处的字符移动到索引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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live