代码随想录算法训练营第三十天| 332 重新安排行程 51 N皇后 37 解数独

目录

332 重新安排行程

51 N皇后 

37 解数独 


332 重新安排行程

回溯

由于题目要求按字典排序返回最小的行程组合,所以对tickets进行排序使其从小到大。在dfs中如果辅助数组path的长度满足要求,就终止所有正在进行的dfs,将当前path添加到结果res中。

class Solution {
    Listres = new ArrayList<>();
    Listpath = new LinkedList<>();
    boolean st[];//标记元素是否被使用过
    public List findItinerary(List> tickets) {
        path.add("JFK");//出发点都是"JFK"
        st = new boolean[tickets.size()];
        tickets.sort(new Comparator>(){
            public int compare(Listo1,Listo2){
                for(int i = 0;i < 2;i++){
                    for(int j = 0;j < 3;j++){
                        int ch1 = o1.get(i).charAt(j) - 'a';
                        int ch2 = o2.get(i).charAt(j) - 'a';
                        if(ch1 != ch2)return ch1 - ch2;//使得从小到大排序
                    }
                }
                return 0;
            }
        });
        dfs(tickets);
        return res;
    }
    private boolean dfs(List>tickets){
        if(path.size() == tickets.size() + 1){//此时全部机票用完,可以返回结果了
            res = new LinkedList(path);
            return true;
        }
        for(int i = 0;i < tickets.size();i++){
            if(st[i])continue;
            if(!path.get(path.size() - 1).equals(tickets.get(i).get(0)))continue;
            path.add(tickets.get(i).get(1));
            st[i] = true;
            if(dfs(tickets))return true;
            st[i] = false;
            path.remove(path.size() - 1);
        }
        return false;
    }
}

哈希映射

51 N皇后 

创建数组row用来存储'Q'的位置,row的下标代表'Q'的层数,下标对应的值代表列数。

创建三个布尔数组col,dg,udg,col用来标记这列是否存在'Q',dg表示对角线截距,用来判断对角线上是否已经存在'Q',udg表示反对角线的截距,用来判断反对角线上是否已经存在'Q'。

如果dfs到末尾,就将row转换为List形式并且加入到返回值res中。

class Solution {
    List>res = new ArrayList<>();
    boolean col[],dg[],udg[];
    //col代表本列是否已经存在'Q'
    //dg表示对角线截距,用来判断对角线上是否已经存在'Q'
    //udg表示反对角线的截距,用来判断反对角线上是否已经存在'Q'
    int row[];
    int N;
    public List> solveNQueens(int n) {
        N = n;
        //由于需要存储对角线,所以应该开辟空间大于2n的辅助数组,且n位于1到9之间
        col = new boolean[20];
        dg = new boolean[20];
        udg = new boolean[20];
        row = new int[N];//存放'Q'的位置,下标代表'Q'的行数,该下标对应的值代表列数
        dfs(0);
        return res;
    }
    private void dfs(int cnt){
        if(cnt == N){
            //将row转换为List,并且加入到res中
            Listnow = new LinkedList();
            char arr[] = new char[N];
            Arrays.fill(arr,'.');
            for(int i = 0;i < N;i++){
                arr[row[i]] = 'Q';
                now.add(new String(arr));
                arr[row[i]] = '.';
            }
            res.add(now);
            return;
        }
        for(int i = 0;i < N;i++){
            //在回溯中记录下'Q'对应的值
            if(!col[i] && !dg[i - cnt + N] && !udg[i + cnt]){
                row[cnt] = i;//记录当前'Q'的位置
                col[i] = dg[i - cnt + N] = udg[i + cnt] = true;
                dfs(cnt + 1);
                col[i] = dg[i - cnt + N] = udg[i + cnt] = false;
            }
        }
    }
}

时间复杂度O(N!)

空间复杂度O(N)

37 解数独 

你可能感兴趣的:(代码随想录算法训练营,算法)