Leetcode算法题-回溯+深度和广度优先搜索

51. N 皇后

https://leetcode-cn.com/problems/n-queens/

class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> res = new ArrayList<>();
        HashSet<Integer> column = new HashSet<>();
        HashSet<Integer> diag1 = new HashSet<>();
        HashSet<Integer> diag2 = new HashSet<>();
        int[] queen = new int[n];
        Arrays.fill(queen,-1);
        dfs(res,column,diag1,diag2, queen, n, 0);
        return res;
    }

    private void dfs(List<List<String>> res, HashSet<Integer> colum, HashSet<Integer> diag1, HashSet<Integer> diag2, int[] queen,int n, int row) {
        if (row == n) {
            List<String> maze = new ArrayList<>(n);
            for (int i = 0; i < n; i++) {
                char[] m_row = new char[n];
                Arrays.fill(m_row, '.');
                m_row[queen[i]] = 'Q';
                maze.add(String.valueOf(m_row));
            }
            res.add(maze);
        } else {
            for (int i = 0; i < n; i++) {
                if (colum.contains(i)) continue;
                if (diag1.contains(row - i)) continue;
                if (diag2.contains(row + i)) continue;
                colum.add(i);
                diag1.add(row - i);
                diag2.add(row + i);
                queen[row] = i;
                dfs(res,colum,diag1,diag2,queen,n,row + 1);
                colum.remove(i);
                diag1.remove(row - i);
                diag2.remove(row + i);
                queen[row] = -1;
            }
        }
    }
}

面试题 04.01. 节点间通路

https://leetcode-cn.com/problems/route-between-nodes-lcci/

class Solution {
    public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
        List<Integer>[] adj = new ArrayList[n];
        for (int[] edge : graph) {
            int from = edge[0];
            int to = edge[1];
            if (adj[from] == null) {
                adj[from] = new ArrayList<>();
            }
            adj[from].add(to);
        }
        return hasPath(n,adj,start,target);    
    }
    
    private boolean hasPath(int n, List<Integer>[] adj, int start, int end) {
        Deque<Integer> queue = new ArrayDeque<>();
        queue.offer(start);
        boolean[] visited = new boolean[n];
        visited[start] = true;
        while (!queue.isEmpty()) {
            int temp = queue.poll();
            if (adj[temp] == null) continue;
            for (Integer num : adj[temp]) {
                if (num == end) return true;
                if (visited[num]) continue;
                visited[num] = true;
                queue.offer(num);
            }
        }
        return false;
    }
}



//深度优先遍历
class Solution {
    public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
        List<Integer>[] adj = new ArrayList[n];
        for (int[] edge : graph) {
            int from = edge[0];
            int to = edge[1];
            if (adj[from] == null) {
                adj[from] = new ArrayList<>();
            }
            adj[from].add(to);
        }
        boolean[] visited = new boolean[n];
        return hasPath(adj,start,target, visited);
    }

    private boolean hasPath(List<Integer>[] adj, int start, int end, boolean[] visited) {
        if (start == end) return true;
        else {
            visited[start] = true;
            if (adj[start] != null) {
                for (int next : adj[start]) {
                    if (!visited[next] && hasPath(adj, next, end, visited)) return true;
                }   
            }
            return false;
        }
    }
}

面试题 08.02. 迷路的机器人

https://leetcode-cn.com/problems/robot-in-a-grid-lcci/

class Solution {
    public List<List<Integer>> pathWithObstacles(int[][] obstacleGrid) {
        List<List<Integer>> res = new ArrayList<>();
        int row = obstacleGrid.length, col = obstacleGrid[0].length;
        if (row == 0 || col == 0) return res;
        boolean[][] visited = new boolean[row][col];
        dfs(obstacleGrid,0,0, visited, res);
        return res;
    }

    private boolean dfs(int[][] obstacleGrid, int x, int y, boolean[][] visited, List<List<Integer>> res) {
        int row = obstacleGrid.length, col = obstacleGrid[0].length;
        if (x >= row || y >= col || obstacleGrid[x][y] == 1 || visited[x][y]) return false;
        if (x == row - 1 && y == col - 1) {
            res.add(Arrays.asList(x,y));
            return true;
        }
        res.add(Arrays.asList(x,y));
        visited[x][y] = true;
        if (dfs(obstacleGrid, x + 1, y, visited, res)) return true;
        if (dfs(obstacleGrid, x, y + 1, visited, res)) return true;
        res.remove(res.size() - 1);
        return false;
    }
}

面试题 08.04. 幂集

https://leetcode-cn.com/problems/power-set-lcci/

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> row = new ArrayList<>();
        dfs(nums, res, row, 0);
        return res;
    }

    public void dfs(int[] nums, List<List<Integer>> res, List<Integer> row,int cur) {
        res.add(new ArrayList<>(row));
        for (int i = cur; i < nums.length; i++) {
            row.add(nums[i]);
            dfs(nums, res, row, i + 1);
            row.remove(row.size() - 1);
        }
    }
}

面试题 08.07. 无重复字符串的排列组合

https://leetcode-cn.com/problems/permutation-i-lcci/

class Solution {
    public String[] permutation(String S) {
        List<String> res = new ArrayList<>();
        dfs(res, S.toCharArray(), 0);
        return res.toArray(new String[0]);
    }
    
    public void dfs(List<String> res, char[] S, int cur) {
        if (cur == S.length) {
            res.add(String.valueOf(S));
        } else {
            for (int i = cur; i < S.length; i++) {
                swap(S, i, cur);
                dfs(res, S, cur + 1);
                swap(S, i, cur);
            }
        }
    }
    
    public void swap(char[] S, int i, int j) {
        char temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }
}

面试题 08.08. 有重复字符串的排列组合

https://leetcode-cn.com/problems/permutation-ii-lcci/

class Solution {
    public String[] permutation(String S) {
        List<String> res = new ArrayList<>();
        char[] s = S.toCharArray();
        Arrays.sort(s);
        boolean[] used = new boolean[s.length];
        dfs(res, "", s,used,0);
        return res.toArray(new String[0]);
    }

    public void dfs(List<String> res, String row, char[] s, boolean[] used, int cur) {
        if (cur == s.length) {
            res.add(row.toString());
        } else {
            for (int i = 0; i < s.length; i++) {
                if (!used[i]) {
                    if (i > 0 && s[i] == s[i - 1] && !used[i - 1]) continue;
                    used[i] = true;
                    dfs(res,row + s[i],s,used, cur + 1);
                    used[i] = false;
                }
            }
        }
    }
}

面试题 08.09. 括号

https://leetcode-cn.com/problems/bracket-lcci/

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> list = new ArrayList<>();
        dfs(list, new char[n * 2], n, n,0,' ');
        return list;
    }

    private void dfs(List<String> list, char[] strs, int left, int right, int index, char temp) {
        if (left > right) return;
        if (left == 0 && right == 0) list.add(new String(strs));
        if (left > 0) dfs(list, strs, left - 1, right, index + 1, strs[index] = '(');
        if (right > 0) dfs(list, strs, left, right - 1, index + 1, strs[index] = ')');
    }
}

面试题 08.10. 颜色填充

https://leetcode-cn.com/problems/color-fill-lcci/

class Solution {
    public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
        if (image[sr][sc] != newColor) {
            dfs(image, sr,sc, image[sr][sc], newColor);
        }
        return image;
    }

    private void dfs(int[][] image, int x, int y, int oldColor, int newColor) {
        int[] dx = {1,0,-1,0};
        int[] dy = {0,1,0,-1};
        int row = image.length, col = image[0].length;
        image[x][y] = newColor;
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if (nx >= 0 && nx < row && ny >= 0 && ny < col && image[nx][ny] == oldColor) {
                dfs(image, nx, ny, oldColor, newColor);
            }
        }
    }
}

面试题 08.12. 八皇后

https://leetcode-cn.com/problems/eight-queens-lcci/

class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> res = new ArrayList<>();
        HashSet<Integer> columns = new HashSet<>();
        HashSet<Integer> diag1 = new HashSet<>();
        HashSet<Integer> diag2 = new HashSet<>();
        int[] queens = new int[n];
        Arrays.fill(queens,-1);
        dfs(res, queens, columns, diag1, diag2, n, 0);
        return res;
    }

    private void dfs(List<List<String>> res,int[] queens, HashSet<Integer> columns, HashSet<Integer> diag1, HashSet<Integer> diag2, int n, int row) {
        if (row == n) {
            List<String> board = generateBoard(queens, n);
            res.add(board);
        } else {
            for (int i = 0; i < n; i++) {
                if (columns.contains(i)) continue;
                int diag_num1 = row - i;
                if (diag1.contains(diag_num1)) continue;
                int diag_num2 = row + i;
                if (diag2.contains(diag_num2)) continue;
                queens[row] = i;
                columns.add(i);
                diag1.add(diag_num1);
                diag2.add(diag_num2);
                dfs(res,queens, columns,diag1,diag2, n,row + 1);
                queens[row] = -1;
                columns.remove(i);
                diag1.remove(diag_num1);
                diag2.remove(diag_num2);
            }
        }
    }
    private List<String> generateBoard(int[] queens, int n) {
        List<String> board = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            char[] row = new char[n];
            Arrays.fill(row, '.');
            row[queens[i]] = 'Q';
            board.add(String.valueOf(row));
        }
        return board;
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值