使两个字符串相等所需的最小给定操作数
给定两个字符串A和B ,两个字符串都包含字符a和b并且长度相等。两个字符串中都有一个_ (空格)。任务是通过执行以下操作的最少次数将第一个字符串转换为第二个字符串:
- 如果_在位置i则_可以与位置i+1或i-1处的字符交换。
- 如果位置i+1和i+2处的字符不同,则_可以与位置i+1或i+2处的字符交换。
- 类似地,如果位置i-1和i-2的字符不同,那么_可以与位置i-1或i-2的字符交换。
例子:
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。
Input: A = “aba_a”, B = “_baaa”
Output: 2
Move 1 : A = “ab_aa” (Swapped A[2] with A[3])
Move 2 : A = “_baaa” (Swapped A[0] with A[2])
Input: A = “a_b”, B = “ab_”
Output: 1
资料来源: Directi 采访集 7
方法:
- 对字符串应用简单的广度优先搜索,用于 BFS 的队列元素将包含对str, pos ,其中pos是_在字符串str中的位置。
- 还要维护一个地图vis ,它将字符串存储为键,并将到达字符串的最小移动存储为值。
- 对于队列中的每个字符串str ,根据给定的四个条件生成一个新字符串tmp并将vis映射更新为vis[tmp] = vis[str] + 1 。
- 重复以上步骤,直到队列为空或生成需要的字符串即tmp == B
- 如果生成了所需的字符串,则返回vis[str] + 1 ,这是将A更改为B所需的最小操作数。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to return the minimum number of
// operations to convert string A to B
int minOperations(string s, string f)
{
// If both the strings are equal then
// no operation needs to be performed
if (s == f)
return 0;
unordered_map vis;
int n;
n = s.length();
int pos = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == '_') {
// store the position of '_'
pos = i;
break;
}
}
// to store the generated string at every
// move and the position of '_' within it
queue > q;
q.push({ s, pos });
// vis will store the minimum operations
// to reach that particular string
vis[s] = 0;
while (!q.empty()) {
string ss = q.front().first;
int pp = q.front().second;
// minimum moves to reach the string ss
int dist = vis[ss];
q.pop();
// try all 4 possible operations
// if '_' can be swapped with
// the character on it's left
if (pp > 0) {
// swap with the left character
swap(ss[pp], ss[pp - 1]);
// if the string is generated
// for the first time
if (!vis.count(ss)) {
// if generated string is
// the required string
if (ss == f) {
return dist + 1;
break;
}
// update the distance for the
// currently generated string
vis[ss] = dist + 1;
q.push({ ss, pp - 1 });
}
// restore the string before it was
// swapped to check other cases
swap(ss[pp], ss[pp - 1]);
}
// swap '_' with the character
// on it's right this time
if (pp < n - 1) {
swap(ss[pp], ss[pp + 1]);
if (!vis.count(ss)) {
if (ss == f) {
return dist + 1;
break;
}
vis[ss] = dist + 1;
q.push({ ss, pp + 1 });
}
swap(ss[pp], ss[pp + 1]);
}
// if '_' can be swapped
// with the character 'i+2'
if (pp > 1 && ss[pp - 1] != ss[pp - 2]) {
swap(ss[pp], ss[pp - 2]);
if (!vis.count(ss)) {
if (ss == f) {
return dist + 1;
break;
}
vis[ss] = dist + 1;
q.push({ ss, pp - 2 });
}
swap(ss[pp], ss[pp - 2]);
}
// if '_' can be swapped
// with the character at 'i+2'
if (pp < n - 2 && ss[pp + 1] != ss[pp + 2]) {
swap(ss[pp], ss[pp + 2]);
if (!vis.count(ss)) {
if (ss == f) {
return dist + 1;
break;
}
vis[ss] = dist + 1;
q.push({ ss, pp + 2 });
}
swap(ss[pp], ss[pp + 2]);
}
}
}
// Driver code
int main()
{
string A = "aba_a";
string B = "_baaa";
cout << minOperations(A, B);
return 0;
}
Python3
# Python3 implementation of the approach
from collections import deque
# Function to return the minimum number of
# operations to convert string A to B
def minOperations(s: str, f: str) -> int:
# If both the strings are equal then
# no operation needs to be performed
if s == f:
return 0
vis = dict()
n = len(s)
pos = 0
for i in range(n):
if s[i] == '_':
# store the position of '_'
pos = i
break
# to store the generated string at every
# move and the position of '_' within it
q = deque()
q.append((s, pos))
# vis will store the minimum operations
# to reach that particular string
vis[s] = 0
while q:
ss = q[0][0]
pp = q[0][1]
# minimum moves to reach the string ss
dist = vis[ss]
q.popleft()
ss = list(ss)
# try all 4 possible operations
# if '_' can be swapped with
# the character on it's left
if pp > 0:
# swap with the left character
ss[pp], ss[pp - 1] = ss[pp - 1], ss[pp]
ss = ''.join(ss)
# if the string is generated
# for the first time
if ss not in vis:
# if generated string is
# the required string
if ss == f:
return dist + 1
# update the distance for the
# currently generated string
vis[ss] = dist + 1
q.append((ss, pp - 1))
ss = list(ss)
# restore the string before it was
# swapped to check other cases
ss[pp], ss[pp - 1] = ss[pp - 1], ss[pp]
ss = ''.join(ss)
# swap '_' with the character
# on it's right this time
if pp < n - 1:
ss = list(ss)
ss[pp], ss[pp + 1] = ss[pp + 1], ss[pp]
ss = ''.join(ss)
if ss not in vis:
if ss == f:
return dist + 1
vis[ss] = dist + 1
q.append((ss, pp + 1))
ss = list(ss)
ss[pp], ss[pp + 1] = ss[pp + 1], ss[pp]
ss = ''.join(ss)
# if '_' can be swapped
# with the character 'i+2'
if pp > 1 and ss[pp - 1] != ss[pp - 2]:
ss = list(ss)
ss[pp], ss[pp - 2] = ss[pp - 2], ss[pp]
ss = ''.join(ss)
if ss not in vis:
if ss == f:
return dist + 1
vis[ss] = dist + 1
q.append((ss, pp - 2))
ss = list(ss)
ss[pp], ss[pp - 2] = ss[pp - 2], ss[pp]
ss = ''.join(ss)
# if '_' can be swapped
# with the character at 'i+2'
if pp < n - 2 and ss[pp + 1] != ss[pp + 2]:
ss = list(ss)
ss[pp], ss[pp + 2] = ss[pp + 2], ss[pp]
ss = ''.join(ss)
if ss not in vis:
if ss == f:
return dist + 1
vis[ss] = dist + 1
q.append((ss, pp + 2))
ss = list(ss)
ss[pp], ss[pp + 2] = ss[pp + 2], ss[pp]
ss = ''.join(ss)
# Driver Code
if __name__ == "__main__":
A = "aba_a"
B = "_baaa"
print(minOperations(A, B))
# This code is contributed by
# sanjeev2552
输出:
2