1 回答
TA贡献1784条经验 获得超8个赞
您走在正确的轨道上,整体形式看起来不错,但细节仍然模糊。
首先,
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 关注
- 109 浏览
添加回答
举报