2020/10/23深度优先遍历

题目

给定一个整数n,将数字1~n排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。

输入格式
共一行,包含一个整数n。

输出格式
按字典序输出所有排列方案,每个方案占一行。

数据范围
1≤n≤7

输入样例:
3

输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

算法解析

深度优先遍历,也就是暴力遍历,关键在于读懂递归函数的功能是什么.
dfs(k)表示的含义是从第k层(从0层开始)开始向下深度优先遍历,并在每次遍历到底时输出所有的path[]数组.
因此,我们能够做到使用递归,处理好第k层,保存好path数据,下面的第k+1层直接使用递归即可.(因为每次输出都会带着本层的结果)
对于层数:因为一共输出三个数,因此一共就只有3层(0,1,2)
算法的另一个关键:回溯
回溯的原因是:我们暂时叫本层为父层,如果让父层选择2,那么子层就永远不能选用2了;但是一旦循环结束,也就是本层在使用其他数,比如3,那么子层的限制条件就修改了,便可以使用2,但是不能使用3了.所以父层在遍历填入每一个数时,对应的需要清理之前留下的痕迹.

变量说明

  • path[i]:用于存储每一层(第i层)使用的数,最后输出的也是这个数组
  • st[i]:表示i这个数有没有被用过.这个数组是公共可见的,也就是每次在选择数的时候都要比对一下这个数组,true表示用过,false表示没用过

源代码

import java.util.*;
class Main{
    static int n;
    static int N=10;
    static int[] path=new int[N];
    static boolean[] st=new boolean[N];
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        dfs(0);
    }
    public static void dfs(int k){
        if(k==n){
            for(int i=0;i<n;i++){
                System.out.print(path[i]+" ");
            }
            System.out.println();
            return ;
        }
        for(int i=1;i<=n;i++){//表示的含义是往坑里填数,当然判断的目的是填的数之前不能用过
            if(!st[i]){ //当前的数没被用过
                st[i]=true; //现在被用过了
                path[k]=i; //尽然用上了那就存好了
                dfs(k+1);
                st[i]=false; //遍历结束要复原,因为循环结束表示当前的坑换数了,就不能让他继续占坑影响下边了
            }
        }
    }
}

备注

为什么传入的参数是0呢?
因为我们让最开始的层数为0层.因为输入的数的个数是n,所以最后一层应该是n-1层. 这样我们在比较的时候,才是

if(k==n)

//这里说的都是从0开始计数)
也就是当前层数是否与(总层数+1)相等,这样才到终止条件;
否则,如果当前层数与总层数相等,那就相当于少列举了一层.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值