DFS

stack【递归也是栈】 o(h) h = 深度,空间稍微少一点,不具有最短性。
回溯、剪枝
对空间要求比较高。
考虑顺序! 俗称暴搜

全排列

图片说明
回溯的时候要恢复现场
图片说明

剑指offer 38. 字符串的排列
class Solution {
    private  Set<String> res;
    private  boolean[] visited;
    private  char[] temp;
    public  String[] permutation(String s) {
        res = new HashSet<>();
        visited = new boolean[s.length()];
        temp = new char[s.length()];
        dfs(s,0);
        return res.toArray(new String[res.size()]);
    }
    private  void dfs(String s,int index) {
        if (index >= s.length()) {
            res.add(new String(temp));
            return;
        }

        for (int i = 0; i < s.length(); i++) {
            if (!visited[i]) { 
                visited[i] = true;
                temp[index] = s.charAt(i);
                dfs(s, index + 1);
                visited[i] = false;
            }
        }
    }

}
leetcode 46
class Solution {
    private List<List<Integer>> res;
    private boolean[] visited;
    private int[] temp;
    private int[] nums;
    public List<List<Integer>> permute(int[] nums) {
        res = new LinkedList();
        temp  = new int[nums.length];
        visited = new boolean[nums.length];
        this.nums = nums;
        dfs(0);
        return res;
    }
    private void dfs(int index) {

        if(index >= nums.length) {
            List<Integer> list = new LinkedList();
            for (int i : temp) {  
                list.add(i);
            }
            res.add(list);
            return;
        }

        for(int i = 0; i < nums.length; i++) {
            if(!visited[i]) {
                visited[i] = true;
                temp[index] = nums[i];
                dfs(index + 1);
                visited[i] = false;
            }
        }

    }

}

BFS

queue o(2^h) 存放的是每一层的节点 空间相对于多一点, 第一次扩展到的点-最短路。
宽搜伪代码: 初始状态放入queue,
while queue不空
拿出队头
扩展队头
从距离数组直接拿到数据

走迷宫

图片说明

//很多时候我们都要去定义一个pair来保存一个节点的key value 
class Pair{
    int key;
    int value;
    Pair(int k,int v){key=k;value=v;}
    public int getKey(){return key;}
    public int getValue(){return value;}
}
class Main{
    private static int n,m;
    private static int[][] p,d;
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();m=sc.nextInt();
        p=new int[n][m];
        d=new int[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                p[i][j]=sc.nextInt();
                //距离值的初始值设为-1用于判断是否遍历过
                d[i][j]=-1;
            }
        }
        System.out.println(bfs());
    }
    //
    public static int bfs(){
        //队列初始化
        Queue<Pair> q=new LinkedList<>();
        //把(0,0)插入队头
        q.add(new Pair(0,0));
        int[] dx={-1,0,1,0},dy={0,1,0,-1};
        while(!q.isEmpty()){
            //取并弹出队头元素
            Pair t=q.poll();
            for(int i=0;i<4;i++){
                int x=t.getKey()+dx[i],y=t.getValue()+dy[i];
                //坐标不越界 && 没被遍历过 && 值为0
                if(x>=0 && x<n && y>=0 && y<m && p[x][y]==0 && d[x][y]==-1){
                    //赋为前一个点的值+1
                    d[x][y]=d[t.getKey()][t.getValue()]+1;
                    q.add(new Pair(x,y));
                }
            }
        }
        //距离起始为-1,最终要+1
        return d[n-1][m-1]+1;
    } 
}

拓扑序列

本身是有向无环图的宽度优先遍历的应用
图片说明
存在环的话,一定有点的入度不为0
一个有向无环图,一定至少存在一个入度为0的点。