通过【lintCode-15全排列问题】学习DFS算法

这周发现毕业一年后自己对于技术的激情好像变得已经没有以前那么热爱与执着了,不再像以前那样每天想着都在学习新的技术,也不再因为每天没有学习到新的东西而会感到负罪感。也或许是我在大公司里由于长期没有压力的工作让我习惯了这样的日子,日复一日的轻松惯了导致的,但偶尔理智的我知道这种轻松的日子并不是我所想要的,至少现阶段不是。干IT这行还是不能堕落原地踏步,得向前看不能掉队,应紧紧跟上科技的浪潮。

————————————————————————————————————————————————————

————————————————————————分隔线—————————————————————————

————————————————————————————————————————————————————

 

描述

给定一个数字列表,返回其所有可能的排列。

题目链接:https://www.lintcode.com/problem/permutations/description

做这个问题如果一时没想到解法,可以先参考一段比这个问题简单的将0-N之前的所有排列全列出来的DFS算法

import java.util.Scanner;

public class dfs {
    public static int[] arr = new int[1000];
    public static int[] flag = new int[1000];//标志哪些数字已经被用

    public static void dfs(int order, int d) {
        if (order == d + 1) {
            for (int i = 1; i <= d; i++)
                System.out.print(arr[i]);
            System.out.println();
            return;
        }
        for (int i = 1; i <= d; i++) {
            if (flag[i] == 0)//如果该数字未被占用
            {
                arr[order] = i;
                flag[i] = 1;//将该数字的访问权限置为1
                dfs(order + 1, d);
                flag[i] = 0;//重新将该数字的访问权限置为0
            }
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("请输入一个全排列数:");
        while (in.hasNextInt()) {
            int ans = in.nextInt();//接收输入的数字
            System.out.println(ans + "的所有全排列如下:");
            dfs(1, ans);
        }
    }

}

其运行结果如下图:

有了上面的可参考代码后,再加以思考,可以发现上面代码的递归过程类似于建立了一颗可回溯的树,通过遍历每一个节点来找到符合条件的所有节点序列。

然后依葫芦画瓢,再将此问题的代码写出来:

代码如下:

import java.util.ArrayList;
import java.util.List;

public class MyDfs {
    public static void main(String[] args) {
        MyDfs myDfs = new MyDfs();
        myDfs.permute(new int[]{1, 2, 3});
    }

    public List<List<Integer>> permute(int[] nums) {
        boolean[] hasAccessFlagArray = new boolean[nums.length];
        int[] tempArray = new int[nums.length];
        List<List<Integer>> resultList = new ArrayList<>();
        dfsFunc(0, tempArray, nums, hasAccessFlagArray, resultList);
        for (List<Integer> integers : resultList) {
            for (Integer integer : integers) {
                System.out.print(integer + " ");
            }
            System.out.println();
        }
        return resultList;
    }

    private void dfsFunc(int index, int[] tempArray, int[] nums, boolean[] hasAccessFlagArray, List<List<Integer>> resultList) {
        if (index == nums.length) {
            List<Integer> subItemList = new ArrayList<>();
            for (int i = 0; i < nums.length; i++) {
                subItemList.add(tempArray[i]);
            }
            resultList.add(subItemList);
        }
        for (int i = 0; i < nums.length; i++) {
            if (!hasAccessFlagArray[i]) {
                hasAccessFlagArray[i] = true;
                tempArray[index] = nums[i];
                dfsFunc(index + 1, tempArray, nums, hasAccessFlagArray, resultList);
                hasAccessFlagArray[i] = false;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水中加点糖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值