算法(回溯算法)

题目:

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

回溯法:一种通过探索所有可能的候选解来找出所有的解的算法。

public class MySort {

    public static void sort() {
        int[] nums = {1, 2, 3, 4};
        int length = nums.length;
        //用于存储得到的结果
        List<int[]> result = new ArrayList<>();
        //用于标识每个元素的状态,并且进行回溯
        boolean[] flag = new boolean[length];
        //初始化一个数组
        int[] num = new int[length];
        doIt(length, nums, 0, num, result, flag);
        //遍历结果,打印日志
        for (int i = 0; i < result.size(); i++) {
            System.err.println(Arrays.toString(result.get(i)));
        }
    }

    public static void doIt(int length, int[] nums, int start, int[] num, List<int[]> list, boolean[] flag) {
        //每次给num数组赋值之后都会将start加1,所以当start==length时满足要求
        if (start == length) {
            //复制数组,并且将数组加到集合里面,如果直接用num,那么得到的结果,每个数组里的值都是一样的
            list.add(num.clone());
            return;
        }
        for (int i = 0; i < length; i++) {
            //因为每个元素只能被用一次,当状态为true时,说明被用过了
            if (flag[i] == true) {
                continue;
            }
            //如果状态不是true就把值赋值给数组,我这里只用了唯一的一个数组去存储,所以,数组里面 的值都是赋值替换的,比较难理解。
            num[start] = nums[i];
            //将该元素状态改为true,表明该元素已经被用了,在这组结果集中不可以再用了
            flag[i] = true;
            doIt(length, nums, start + 1, num, list, flag);
            //将状态改为false,说明我们已经得到了一组解或者前一个步骤得整个方法走完了,表明该元素可以用了,会继续寻找所有满足结果的解
            flag[i] = false;
        }
    }
}

个人总结用回溯算法的小技巧(可以不看哈,这是自己的一点总结,最重要的还是得搞懂它得原理,能理清逻辑,逻辑里不过来就debug,或者在纸上画一画):

1.首先我们不管三七二十一,就先把这个数组得长度计算出来int length = nums.length;,别问,写下来,肯定要用,算法 题很少不用计算长度的,哈哈

2,看例子,输出,那肯定是个集合,直接写个List<int[]> result = new ArrayList<>();肯定用来存储结果,有了集合那肯定少不了,int[] num = new int[length],都写出来,写着写着,就用到了;

3,回溯么,肯定是有一个存储元素得状态,是个数组,那我们就少不了:boolean[] flag = new boolean[length],每个元素状态初始值都是false;

4,接下来,就单独写个方法,这是重点。哈哈,我们就把那些定义的东西,当方法的参数传进来。

5,回溯么,那我们肯定是需要结束得标识,那肯定是达到了数组得长度。

6,接着就是遍历这个数组,然后把已经用了的元素,把它状态改为true,

7,再递归调用这个方法,最后再把状态改为false,

8,再不断修修改改,debug,你突然发现,答案出来了,是不是很神奇

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值