Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
有一种特殊的DNA,仅仅由核酸A和T组成,长度为n,顺次连接。科学家有一种新的手段,可以改变这种DNA。每一次,科学家可以交换该DNA上两个核酸的位置,也可以将某个特定位置的核酸修改为另一种核酸。现有一个DNA,科学家希望将其改造成另一种DNA,希望你计算最少的操作次数。
输入:
ATTTAA
TTAATT
输出:
3
二、思路分析
本题主要考察对于给定的两个字符串,如何将原字符串通过操作变换为目标字符串,在对原字符串进行变换时可以变更原字符串中的字符或调换原字符串中字符的顺序,并要求输出最小的操作次数。由于本题的字符串中仅包含A与T,所以可以首先对原字符串通和目标字符串中A与T的数量分别进行统计,并将原字符串中A与T的数量变换为与目标字符串中A与T的数量相同,之后再对原字符串进行调换字符操作,使之变为与目标字符串的字符排列顺序相同。
注意:
1.在对原字符串进行变更字符时(由T变为A或A变为T),需要与目标字符串进行比对,遇到与目标字符串字符不匹配时再进行变更,并重新计数(A+1,T-1 或 A-1,T+1)变更完成后保证原字符串中A与T的数量与目标字符串中A与T的数量相同。时间复杂度为 O(n)
2.在进行字符对调时并不需要真正的进行字符对调,只需要将经过变更字符后的原字符串与目标字符串进行对此,统计出两个字符串字符不相同的个数 n,则 n/2 就是需要进行对调的次数,之后再加上变更字符的次数就得到最小的操作次数。时间复杂度为 O(n)
三、代码
func DNAMatch(src, dst string) int {
res := 0
n := 0
srcbyte := []byte(src)
dstbyte := []byte(dst)
srcmap := make(map[byte]int)
dstmap := make(map[byte]int)
for i := 0; i < len(src); i++ {
srcmap[src[i]]++
dstmap[dst[i]]++
}
for i := 0; i < len(src) && srcmap['A'] < dstmap['A']; i++ {
if src[i] == 'T' && dst[i] == 'A' {
srcbyte[i] = byte('A')
res++
srcmap['A']++
srcmap['T']--
}
}
for i := 0; i < len(src) && srcmap['A'] > dstmap['A']; i++ {
if src[i] == 'A' && dst[i] == 'T' {
srcbyte[i] = byte('T')
res++
srcmap['A']--
srcmap['T']++
}
}
for i := 0; i < len(srcbyte); i++ {
if srcbyte[i] != dstbyte[i] {
n++
}
}
return res + n/2
}
四、总结
此方法虽然简单易懂,使用模拟的方法,对字符串进行变换。但需要开辟大量额外的空间来存储统计出来的A与T的数量,并且在对字符串中的字符进行变换时需要将字符串转换为字符数组再进行操作,又开辟了多余的空间。所以此方法空间消耗较大。优化时可以考虑如何减小空间开销。提升代码性能。