给定 2 个字符串和整数 k,以 k 步将一个字符串转换为另一个字符串
Posted
技术标签:
【中文标题】给定 2 个字符串和整数 k,以 k 步将一个字符串转换为另一个字符串【英文标题】:Given 2 strings and integer k, convert one string into another in exactly k steps 【发布时间】:2020-05-17 14:49:30 【问题描述】:我正在解决“HackerRank”页面上的一个问题,特别是名为“追加和删除”的问题,但我无法使所有案例都正确。
https://www.hackerrank.com/challenges/append-and-delete/problem
"你有一串小写英文字母。你可以 对字符串执行两种类型的操作:
在字符串末尾附加一个小写英文字母。 删除字符串中的最后一个字符。执行此操作 空字符串导致空字符串。给定一个整数, 和 两个字符串,and ,确定是否可以转换为 by 在 上执行上述操作。如果它是可能的, 打印是的。否则,打印编号。
例如,字符串和 .我们的移动次数, .要转换为 ,我们 首先删除移动中的所有角色。接下来我们添加每个 字符的顺序。在移动中,您将拥有匹配的 细绳。如果有更多可用的动作,他们本来可以 通过对空字符串执行多次删除来消除。如果 有少于移动,我们不会成功地创造 新字符串。
功能说明
在下面的编辑器中完成 appendAndDelete 功能。这应该 返回一个字符串,是或否。
appendAndDelete 具有以下参数:
s:初始字符串 t:所需字符串 k:整数 表示操作数”。
int cont = 0;
int limite = 0;
if (s.length() < t.length())
limite += s.length();
else if (s.length() >= t.length())
limite += t.length();
for (int i = 0; i < limite; i++)
if (s.charAt(i) != t.charAt(i))
cont += 2;
int diferen = 0;
if (s.length() != t.length())
diferen += (Math.abs(t.length() - s.length()));
cont += diferen;
if(cont <= k)
return "Yes";
else
return "No";
【问题讨论】:
【参考方案1】:简介
要发现代码中的问题,让我们对其进行简化。
简化limite
计算
要计算limite
值,您可以使用if/else
块,如下所示:
if (s.length() < t.length())
limite += s.length();
else if (s.length() >= t.length())
limite += t.length();
但是,由于您的 limite
在此块之前始终是 0
并且您正在寻找的是最短字符串的长度,您可以简单地将其替换为:
int limite = Math.min(s.length(), t.length());
简化diferen
计算
同样,您不需要任何if
块来计算您的diferen
- 如果两个字符串的长度相同,那么diferen
就是0
,这就是Math.abs(t.length() - s.length())
也会产生的结果。
所以,不要这样:
int diferen = 0;
if (s.length() != t.length())
diferen += (Math.abs(t.length() - s.length()));
您可以简单地使用单线:
int diferen = (Math.abs(t.length() - s.length()));
更好的变量名
diferen
或 cont
或 limite
这样的变量名称令人困惑。相反,您可以将这些变量重命名为 absLengthDifference
、operationCount
和 commonLength
。
您的简化代码
static String appendAndDelete(String s, String t, int k)
int operationCount = 0;
int shorterStringLength = Math.min(s.length(), t.length());
for (int i = 0; i < commonLength; i++)
if (s.charAt(i) != t.charAt(i))
operationCount += 2;
int absLengthDifference = (Math.abs(t.length() - s.length()));
operationCount += absLengthDifference;
if(operationCount <= k)
return "Yes";
return "No";
发现逻辑错误
因此,根据简介中所做的修改,我们将找出程序产生错误结果的原因。
让我们考虑如下输入:
ab
bb
2
您的程序将对此作出肯定的判断,因为 operationCount
将是 2
但 operationCount <= 2
。所以,这是不正确的,因为要在任务中使用操作将ab
转换为bb
,我们必须执行以下操作:
'ab' -> 'a' |到达“a”的唯一方法是删除“b”
'a' -> '' |纠正“a”的唯一方法是先将其删除
'' -> 'b' |然后附加'b'
'b' -> 'bb' |最后,再次追加'b'
如您所见,我们需要4
操作才能达到预期的结果,而不是2
。因此,下面的块是错误的:
for (int i = 0; i < commonLength; i++)
if (s.charAt(i) != t.charAt(i))
operationCount += 2;
添加是不够的2
。如果您发现不匹配,则必须从末尾删除所有字符才能找到它(如示例中所示)。
另外,if(operationCount <= k)
是错误的,因为操作数必须正好是k
。
解决办法
-
首先要意识到的是,如果
k
大于或等于字符串长度的总和,那么答案是Yes
。我们可以从原始字符串s
中删除所有字符,并继续从空字符串0
中删除一个字符或更多次,然后从目标字符串t
中追加字符。
否则,如果找到两个公共字符串的长度commonLength
,那么我们可以在s.length() + t.length() - 2*commonLength
步骤中将s
转换为t
。但是,由于显而易见的原因,该值 minOperationCount
不能大于 k
。此外,如果小于k
,则k - minOperationCount
必须是2
的倍数。如果不是,则可以完全按照k
步骤进行转换。
代码
// Complete the appendAndDelete function below.
static String appendAndDelete(String s, String t, int k)
int totalLength = s.length() + t.length();
if (totalLength <= k)
return "Yes";
int commonLength = 0;
for (int i = 0; i < Math.min(s.length(), t.length()); i++)
if (s.charAt(i) != t.charAt(i))
break;
commonLength++;
int minOperationCount = totalLength - 2 * commonLength;
if(minOperationCount <= k && ((k - minOperationCount) % 2 == 0))
return "Yes";
return "No";
【讨论】:
以上是关于给定 2 个字符串和整数 k,以 k 步将一个字符串转换为另一个字符串的主要内容,如果未能解决你的问题,请参考以下文章