暴力递归(golang)

174 阅读2分钟

汉诺塔 的图像结果

如何在保持大套圈在小套圈下面的规则下,将所有套圈套到另一根柱子上

问题分解:

假设有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)
}