github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/datastructures/recursion/permutation_test.go (about)

     1  package recursion
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"testing"
     7  )
     8  
     9  // 递归实现全排列
    10  // 思路: 可以画出递归树图进行递归解析, abcd -> axxx, bxxx, cxxx dxxx;
    11  //
    12  /*
    13  时间复杂度分析
    14  递推公式: f(n) = n*f(n-1)
    15  对递推公式求和: Σ = n + n*f(n-1) + n*(n-1)*f(n-2) + ...
    16  所以的 O(n!)~O(n*n!) 之间
    17  
    18  */
    19  func permutation(arr []interface{}, start, dep int) {
    20  	len := len(arr)
    21  	if start == len-1 { // 最后一位
    22  		fmt.Println("dep:", strconv.Itoa(dep), arr)
    23  	} else {
    24  		for i := start; i < len; i++ {
    25  			// i = start 时输出自己
    26  			// 如果i和start的值相同就没有必要交换
    27  			if i == start || arr[i] != arr[start] { // 减枝操作
    28  				//交换当前这个与后面的位置
    29  				arr[i], arr[start] = arr[start], arr[i]
    30  				fmt.Printf("dep:%v swap1: %v, start:%v\n", dep, arr, start)
    31  				//递归处理索引+1
    32  				permutation(arr, start+1, dep+1)
    33  				//换回来,因为是递归,如果不换回来会影响后面的操作,并且出现重复
    34  				arr[i], arr[start] = arr[start], arr[i]
    35  				fmt.Printf("dep:%v swap2: %v, start:%v\n", dep, arr, start)
    36  			}
    37  		}
    38  	}
    39  }
    40  
    41  func Test_permutation(t *testing.T) {
    42  	//slice1 := make([]interface{}, 4)
    43  	//for i := 0; i < 4; i++ {
    44  	//	slice1[i] = i + 1
    45  	//}
    46  	//permutation(slice1, 0)
    47  
    48  	slice2 := make([]interface{}, 3)
    49  	slice2[0] = "a"
    50  	slice2[1] = "b"
    51  	slice2[2] = "c"
    52  	permutation(slice2, 0, 1)
    53  	//fmt.Printf("permutation after %v\n", slice2)
    54  }