全排列-回溯

回溯简介:

程序在运行过程中分成了多个阶段。

通过某些手段,将数据恢复到之前某一阶段,这就称之为回溯。

手段包括: ①方法栈  ②自定义栈

比如给数字1, 2, 3进行全排列。我们可以先固定数字1, 对2,3进行排列;然后固定2,对1,3进行排列;最后固定3,对1,2进行排列。

在代码实现时,我们需要准备两个数组,一个代表原始数组【1,2,3】,另一个数组,用来表示数字是否已固定(被使用过),已固定用灰色表示,未固定绿色表示。是个boolean变量。

比如说一开始固定1,同时把固定好的元素加入集合中,集合中就存储着我们的排列。紧接着固定2,最后剩下3,然后固定3。形成一种排列,只要集合的大小和数组长度一致时,就表示找到了其中一种排列。

                                                              

然后我们需要用回溯法把数据恢复到有几个元素没有被固定的状态,继续找其他排列。依此类推。

找到其他排列如下图。

注意:

以上方法只适用于无重复元素的全排列。

代码实现:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class PermuteLeetcode46 {

    public static void main(String[] args) {
        List<List<Integer>> permute = permute(new int[]{1, 2, 3});
        for (List<Integer> s : permute) {
            System.out.println(s);
        }
    }

    public static List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        dfs(nums, new boolean[nums.length], new LinkedList<>(), result);
        return result;
    }

    public static void dfs(int[] nums, boolean[] visited, LinkedList<Integer> stack, List<List<Integer>> result){

        if(stack.size() == nums.length){
            result.add(new ArrayList<>(stack));  //stack中的元素会不断变化,要把它里面的元素放入一个新集合
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (!visited[i]) {
                stack.push(nums[i]);
                visited[i] = true;
                dfs(nums, visited, stack, result);
                visited[i] = false;
                stack.pop();
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值