8月28日 阿里笔试
第1题
如果对于一个 01 字符串,每次可以进行如下操作中的一种。
- 只能交换任意两个元素
- 把一个0变成1或把一个1变成0
- 翻转整个字符串
请问从A串变成B串最少需要多少步?
我们先分析一波。

我们要用三种操作将字符串 origin 变成 target。
尽管不一定最优,假设我们得到了一种可行方案。
假设这个方案里的翻转次数 r>1,那么我们一定可以消除其中的两次翻转操作达到一样的效果。
现在我们的方案里只有0次或1次翻转操作。假设现在我们的方案里仍然有1次翻转操作,那么翻转操作一定可以挪到最开始首先进行。那么我们得到翻转字符串 reversed。
那么就得到两种可能的方案。
第一种:将字符串 origin 进行 交换 或 改变 得到 target。
第二种:将字符串 origin 翻转 得到 reversed, 再对 reversed 进行 交换 或 改变 得到 target。
我无法判断在这两种情况中哪一种转化为 target 所需要的步数更少。因此我们对字符串 origin 和 reversed 都进行受限的转换(交换 或 改变)得到 target,并比较总步数取较小值。
接下来我们继续考虑用受限的转换将字符串 origin 变成 target。
交换一次消一对,改变一次消一个。
能交换的时候我们无脑交换就行了。
origin 和 target不匹配有两种情况:
dismatch0: origin[i]=='1' && target[i]=='0'dismatch1: origin[i]=='0' && target[i]=='1'
如果两类不匹配分别有 dismatch0,dismatch1 个。
那么我们可以用交换消除 min(dismatch0,dismatch1),剩余的不匹配用改变逐一处理。
交换和改变的次数之和为 max(dismatch0,dismatch1)。
package main
import "fmt"
func convert(origin,target string) (n int) {
k:=0
for i:=0;i< len(origin);i++{
if origin[i]!=target[i]{
k++
}
}
reversed:=""
for _,v:=range origin{
reversed=string(v)+reversed
}
return min(1+convertBanRev(reversed,target),convertBanRev(origin,target))
}
func convertBanRev(origin,target string) (n int

本文分享了8月28日阿里笔试中研发工程师C/C++岗位的两道题目。第一题讨论如何从字符串A转换到字符串B的最小步骤,分析了不同操作的影响。第二题涉及全排列问题,通过Go语言的特性解释了解题思路,并提到C++的next_permutation函数在解决全排列问题上的高效应用。

140

被折叠的 条评论
为什么被折叠?



