如何在保持大套圈在小套圈下面的规则下,将所有套圈套到另一根柱子上
问题分解:
假设有n个套圈,需要转移到右边的柱子
第一步:
将n-1个套圈套到中间(other)上
第二步:
将第n个套圈套到右边柱子(to)上
第三步:
将n-1个套圈从other柱移动到to上
我们定义一个func process (from ,to ,other,i)
第一步 process(左,中,右,n-1)
第二步 打印 将第8个 左 移到 右
第三步 process(中,右,左,n-1)
base case(退出递归)是什么?
当它是最顶层的那个(n==1),它可以随便移动
package main
import "fmt"
func hanoi(n int) {
if n > 0 {
process("左", "右", "中", n)
}
}
func process(from, to, other string, n int) {
if n == 1 {
fmt.Println("Move 1 from ", from, " to", to)
} else {
process(from, other, to, n-1)
fmt.Println("Move ", n, " from ", from, " to ", to)
process(other, to, from, n-1)
}
}
func main() {
hanoi(3)
}
打印结果:
Move 1 from 左 to 右 Move 2 from 左 to 中 Move 1 from 右 to 中 Move 3 from 左 to 右 Move 1 from 中 to 左 Move 2 from 中 to 右 Move 1 from 左 to 右
求一个字符串所有的排序
输入,abc
返回
abc acb bac bca cba cab
问题分解
第一步:在字符串i的位置上,把位置i及后面的字符都放到当前位置i上,位置0放abc
第二步:在位置i+1上,把位置i+1及后面的字符都放在位置i+1上
第三步:当位置i走到结尾时,打印当前字符串
定义一个方法process(arr,i)
第一步:把i后面的字符都放到i位置上
for j := i; j < len(str); j++ { str = swap(str, i, j) }
第二步:然后i+1也放剩余字符,要换回来成原来的样子,轮到下一个字符到i+1位置
for j := i; j < len(str); j++ {
str = swap(str, i, j)
process(str, i+1)
str = swap(str, i, j)
}
第三步:当i走到结尾,打印字符串
if i == len(str) {
fmt.Println(strings.Join(str, ""))
return
}
package main
import (
"fmt"
"strings"
)
func process(str []string, i int) {
if i == len(str) {
fmt.Println(strings.Join(str, ""))
return
}
for j := i; j < len(str); j++ {
str = swap(str, i, j)
process(str, i+1)
str = swap(str, i, j)
}
}
func swap(arr []string, i, j int) []string {
if i == j {
return arr
}
temp := arr[i]
arr[i] = arr[j]
arr[j] = temp
return arr
}
func main() {
process(strings.Split("abc", ""), 0)
}