字符串解码问题 | 豆包MarsCode AI刷题
简单题,可以学习golang中strings.Builder的使用
摘要
本文介绍了如何对字符串进行解码。通过替换特定字符并保持其他字符不变,我们可以高效地完成解码任务。本文提供了Python和Go的代码实现,时间复杂度为 。
问题描述
给定字符串 和替换规则:
'x'替换为'y','y'替换为'x'。'a'替换为'b','b'替换为'a'。- 其他字符保持不变。
要求返回解码后的字符串。
示例
输入
N = 5, S = "xaytq"
输出
"ybxtq"
原理分析
替换规则
- 遍历字符串 ,对每个字符检查是否需要替换。
- 若字符为
'x'、'y'、'a'或'b',则替换为相应的字符;否则保持原样。
算法步骤
- 初始化结果列表,用于存储解码后的字符。
- 遍历字符串,按照替换规则处理每个字符。
- 拼接结果列表为字符串并返回。
在 Go 中,strings.Builder 是用于高效构建字符串的工具。与直接使用字符串拼接相比,strings.Builder 可以减少内存分配的次数,从而提升性能,特别是在需要频繁拼接字符串的场景中。
使用 strings.Builder 的典型场景
- 字符串的高效拼接:避免多次内存分配。
- 动态生成长字符串:例如生成 HTML、JSON 等复杂结构。
- 性能优化:特别是在循环中拼接字符串时。
基本用法
以下是 strings.Builder 的常见用法:
package main
import (
"fmt"
"strings"
)
func main() {
var builder strings.Builder
// 使用 WriteString 添加字符串
builder.WriteString("Hello")
builder.WriteString(", ")
builder.WriteString("World!")
// 获取拼接后的字符串
result := builder.String()
fmt.Println(result) // 输出: Hello, World!
}
方法说明
1. WriteString(s string) (int, error)
向 Builder 中追加一个字符串。
builder.WriteString("Hello")
2. Write(b []byte) (int, error)
向 Builder 中追加字节切片。
builder.Write([]byte("Hello"))
3. WriteRune(r rune) (int, error)
向 Builder 中追加一个 Unicode 字符(rune)。
builder.WriteRune('世')
builder.WriteRune('界')
4. Grow(n int)
提前为 Builder 分配至少 n 字节的内存,减少后续内存分配次数。
builder.Grow(100) // 预分配 100 字节空间
5. String() string
获取当前 Builder 中的拼接结果。
result := builder.String()
6. Reset()
清空 Builder 的内容,可以重复使用。
builder.Reset()
示例:动态生成 JSON
strings.Builder 非常适合用来构造结构化字符串,例如 JSON。
package main
import (
"fmt"
"strings"
)
func main() {
var builder strings.Builder
builder.WriteString("{")
builder.WriteString(`"name": "Alice", `)
builder.WriteString(`"age": 25`)
builder.WriteString("}")
result := builder.String()
fmt.Println(result)
}
输出:
{"name": "Alice", "age": 25}
示例:循环拼接字符串
在循环中使用 strings.Builder 拼接字符串时,可以显著提升性能。
package main
import (
"fmt"
"strings"
)
func main() {
var builder strings.Builder
builder.Grow(50) // 预分配空间,提升性能
for i := 0; i < 5; i++ {
builder.WriteString(fmt.Sprintf("Line %d\n", i+1))
}
fmt.Println(builder.String())
}
输出:
Line 1
Line 2
Line 3
Line 4
Line 5
性能对比:strings.Builder vs 字符串拼接
示例代码
package main
import (
"strings"
"testing"
)
func BenchmarkBuilder(b *testing.B) {
for i := 0; i < b.N; i++ {
var builder strings.Builder
builder.Grow(1000)
for j := 0; j < 1000; j++ {
builder.WriteString("a")
}
_ = builder.String()
}
}
func BenchmarkStringConcat(b *testing.B) {
for i := 0; i < b.N; i++ {
str := ""
for j := 0; j < 1000; j++ {
str += "a"
}
}
}
结果
strings.Builder 的性能会显著优于直接的字符串拼接,尤其是拼接次数较多时。
注意事项
- 单线程使用:
strings.Builder不是线程安全的,不能在多个 goroutine 中同时使用。
- 不可复制:
Builder是一种带状态的对象,不能复制。如果复制一个Builder,会导致未定义行为。
代码实现
Python代码
def solution(N: int, S: str) -> str:
"""
根据字符的替换规则转换字符串 S:
- 'x' 替换为 'y'
- 'y' 替换为 'x'
- 'a' 替换为 'b'
- 'b' 替换为 'a'
其余字符保持不变。
"""
# 使用列表存储替换后的字符,避免频繁字符串拼接
result = []
# 遍历字符串 S 的每个字符
for ch in S:
if ch == 'x':
result.append('y')
elif ch == 'y':
result.append('x')
elif ch == 'a':
result.append('b')
elif ch == 'b':
result.append('a')
else:
result.append(ch)
# 将字符列表转换为字符串并返回
return ''.join(result)
if __name__ == "__main__":
# 测试用例
print(solution(5, "xaytq") == "ybxtq") # 应输出 True
print(solution(6, "abcxyz") == "bacyxz") # 应输出 True
print(solution(3, "zzz") == "zzz") # 应输出 True
Go语言代码
package main
import (
"fmt"
"strings"
)
func solution(N int, S string) string {
var builder strings.Builder
for i := 0; i < len(S); i++ {
if S[i] == 'x' {
builder.WriteRune('y')
} else if S[i] == 'y' {
builder.WriteRune('x')
} else if S[i] == 'a' {
builder.WriteRune('b')
} else if S[i] == 'b' {
builder.WriteRune('a')
} else {
builder.WriteRune(rune(S[i]))
}
}
return builder.String()
}
func main() {
fmt.Println(solution(5, "xaytq") == "ybxtq")
fmt.Println(solution(6, "abcxyz") == "bacyxz")
fmt.Println(solution(3, "zzz") == "zzz")
}