Go语言 如何实现回溯型问题的递归选择

db2dz4w8  于 2023-08-01  发布在  Go
关注(0)|答案(3)|浏览(101)

我很难理解如何在递归回溯问题中实现“选择”。
我有以下代码来查找给定int切片的所有排列:

func permute(nums []int) [][]int {
    res := [][]int{}
    tmp := []int{}

    var helper func( []int)
    helper = func(toChoose []int) {
        if len(toChoose) == 0{
            cp := make([]int, len(tmp))
            copy(cp, tmp)
            res = append(res, cp)
            return
        }

        for i, _ := range toChoose{ 
            tmp = append(tmp, toChoose[0])
            toChoose = toChoose[1:]
            helper(toChoose)
        }
    }

    helper(nums)
    return res
}

字符串
基本上,根据我的理解,在一个结果数组中的每个插槽中,我需要决定从输入中选择一个数字,例如:
输入:[1,2]
对于插槽0,选择索引1或0
对于插槽1,选择剩余的索引
我们得到结果:[1、2]、[2、1]
如何递归地实现“decision”?我认为这是我完全理解回溯和递归的关键。

qnakjoqk

qnakjoqk1#

你可以尝试使用下一个排列算法。查看this文章。这并不完全是为Golang写的,但想法是一样的。基本上,给定一个数组,next permutation对数组执行一些交换操作,并给出下一个置换。所以,如果你给予他们一个[1,2,3]的数组,下一个排列将是[1,3,2],然后下一个排列将是[2,1,3],然后[2,3,1],然后[3,1,2],然后[3,2,1]。你可以反复调用next permutation来列出所有可能的排列。
在C++中,我们在标准库中有这个算法。对于Golang,我想你可以看看this

pxq42qpu

pxq42qpu2#

1.如何保存每个元素的状态(它已被使用或可用),你可以使用像数组,位操作
1.何时退出递归。在你的问题中,当数组中的所有元素都被使用时,递归就结束了。
下面是一个Java示例

/**
 * 
 * @param visited    to save using states of arr elements
 * @param arr        source array
 * @param list       the used elements in permutation
 * @param count      how many elements have beed used, when it equals arr's length, one permutation is over
 */
public void dfs(boolean[] visited, int[] arr, LinkedList<Integer> list, int count)
{

    //the end of the permutation
    if (count == arr.length)
    {
        System.out.println(list.toString());
        return;
    }

    for (int i = 0; i < arr.length; i++)
    {
        if (visited[i])
        {
            continue;
        }

        //to mark arr[i] has been used, you can't use it before set visited[i] to false
        visited[i] = true;

        //add arr[i] to permutation list
        list.add(arr[i]);

        //now the num of used arr elements is count+1
        dfs(visited, arr, list, count + 1);

        //remove arr[i] from permutation list
        list.removeLast();

        //now arr[i] is available
        visited[i] = false;
    }

字符串

64jmpszr

64jmpszr3#

有多种方法可以递归地处理置换。递归的一种方法经常应用于列表,它是取列表中的一个成员,然后递归列表的其余部分。
那你的问题就是假设我们已经有了不包含这个元素的列表的所有排列,那么我们应该对包含这个元素的列表执行什么操作来实现包含这个元素的排列呢?
在伪代码中:

permute(nums) {
  // One base case: if nums has one element,
  // what do we return?

  var x = nums[0]
  var rest = permute(nums[1:])

  // How to apply x to each permutation
  // of the rest of the list?
  //
  // For example:
  // input [1, 2, 3]
  // rest = [[2, 3], [3, 2]]
  // What do we do with 1 and each of those
  // permutations to build permutations of
  // length 3?
}

字符串

相关问题