github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/leetcode/permutations_test.go (about)

     1  package leetcode
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"testing"
     7  )
     8  
     9  // 46. 全排列
    10  //https://leetcode-cn.com/problems/permutations/
    11  
    12  // 思路: 使用递归回溯法
    13  func permute(nums []int) [][]int {
    14  	if len(nums) == 0 {
    15  		return nil
    16  	}
    17  	if len(nums) == 1 {
    18  		return [][]int{{nums[0]}}
    19  	}
    20  	if len(nums) == 2 {
    21  		return [][]int{{nums[0], nums[1]}, {nums[1], nums[0]}}
    22  	}
    23  
    24  	var result [][]int
    25  	for index, value := range nums {
    26  		var numsCopy = make([]int, len(nums))
    27  		copy(numsCopy, nums)
    28  		// 将numsCopy中index这个元素给剔除掉赋值给numsSubOne
    29  		numsSubOne := append(numsCopy[:index], numsCopy[index+1:]...)
    30  		valueSlice := []int{value}
    31  		newSubSlice := permute(numsSubOne)
    32  		for _, newValue := range newSubSlice {
    33  			result = append(result, append(valueSlice, newValue...))
    34  		}
    35  	}
    36  	return result
    37  }
    38  
    39  // 47  全排列2,nums中有重复的元素
    40  func permuteUnique(nums []int) [][]int {
    41  	if len(nums) == 0 {
    42  		return nil
    43  	}
    44  	if len(nums) == 1 {
    45  		return [][]int{{nums[0]}}
    46  	}
    47  	if len(nums) == 2 {
    48  		if nums[0] == nums[1] { // 与前一个数相等 只返回一种可能性
    49  			return [][]int{{nums[0], nums[1]}}
    50  		} else {
    51  			return [][]int{{nums[0], nums[1]}, {nums[1], nums[0]}}
    52  		}
    53  	}
    54  	// 先排序
    55  	sort.Ints(nums)
    56  	var result [][]int
    57  	for index, value := range nums {
    58  		var numsCopy = make([]int, len(nums))
    59  		copy(numsCopy, nums)
    60  		if index > 0 && numsCopy[index] == numsCopy[index-1] {
    61  			continue
    62  		}
    63  		// 将numsCopy中index这个元素给剔除掉赋值给numsSubOne
    64  		numsSubOne := append(numsCopy[:index], numsCopy[index+1:]...)
    65  		valueSlice := []int{value}
    66  		newSubSlice := permuteUnique(numsSubOne)
    67  		for _, newValue := range newSubSlice {
    68  			result = append(result, append(valueSlice, newValue...))
    69  		}
    70  	}
    71  	return result
    72  }
    73  
    74  func TestPermute(t *testing.T) {
    75  	nums := []int{1, 2, 3}
    76  	res := permute(nums)
    77  	fmt.Println(res)
    78  }
    79  
    80  func TestPermute2(t *testing.T) {
    81  	nums := []int{1, 1, 1, 2}
    82  	//res := permuteUnique(nums)
    83  	res := permuteUnique2(nums)
    84  	fmt.Println(res)
    85  }
    86  
    87  func permuteUnique2(nums []int) [][]int {
    88  	var res [][]int
    89  	// 先排序
    90  	sort.Slice(nums, func(i, j int) bool {
    91  		return nums[i] < nums[j]
    92  	})
    93  	used := make([]bool, len(nums))
    94  	var stack []int
    95  	permuteHelper(0, nums, used, stack, &res)
    96  	return res
    97  }
    98  
    99  func permuteHelper(index int, nums []int, used []bool, stack []int, res *[][]int) {
   100  	n := len(nums)
   101  	if index == n {
   102  		// 出口已经找到
   103  		arr := make([]int, n)
   104  		copy(arr, stack)
   105  		*res = append(*res, arr)
   106  		return
   107  	}
   108  	for i := 0; i < n; i++ {
   109  		if !used[i] {
   110  			if i > 0 && nums[i] == nums[i-1] && used[i-1] {
   111  				continue
   112  			}
   113  			used[i] = true
   114  			permuteHelper(index+1, nums, used, append(stack, nums[i]), res)
   115  			used[i] = false
   116  		}
   117  	}
   118  
   119  }