1 回答
TA贡献1906条经验 获得超3个赞
你在正确的轨道上,整体形式看起来不错,但细节仍然模糊。
首先,
newS := s[:idx]
suffix := s[idx : idx+1]
newS += suffix
相当于
newS := s[:idx+1]
这里没有进行真正的置换;这是切断字符串的背面并i完全忽略循环变量。尝试为每个递归调用交换字符串中的两个字符并使用两者i并idx这样做;将其视为一个固定的枢轴,用于将每个元素与每个调用帧idx交换。i...len(s)不过,确保您没有重新分配给当前范围内的字符串,这很好,因为这会为以后的循环迭代弄乱状态。
第二个建议:要建立基本情况,递归地向上计数len(s)而不是向下计数为零。您几乎可以假装数组的整个第一个块不存在。把它想象成一个常规的排列算法,除了你跳过了第一个idx索引。
此外,这更像是一个设计点而不是算法问题,但我会将idx参数公开给调用者,而不是将其隐藏在包装器后面。这使得该函数可重用,并且它的作用更明显——作为库的用户,如果一个名为的函数permute拒绝置换前 2 个字符,我会感到困惑。
最好返回一个结果而不是产生像打印这样的副作用,但为了教学,我会把它放在一边。
这是一种解决方案(剧透警告!):
package main
import "fmt"
func permute(s string, idx int) {
if idx == len(s) {
fmt.Println(s)
}
for i := idx; i < len(s); i++ {
a := []rune(s)
a[i], a[idx] = a[idx], a[i]
permute(string(a), idx + 1)
}
}
func main() {
permute("abcde", 2)
}
permute("abcde", 2)生产
abcde
abced
abdce
abdec
abedc
abecd
- 1 回答
- 0 关注
- 121 浏览
添加回答
举报