Day23 | 51N 皇后&37解数独&491非递减子序列&332重新安排行程

134 阅读2分钟

N 皇后 LeetCode 51

题目链接:[LeetCode 51 - 困难]

思路

主要解决方式:1.设置一个回溯的方法2.判断是否存在同一行或同一列或同一斜线上

回溯:

class Solution {
    List<List<String>> result = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        char[][] chessboard = new char[n][n];

        for(char[] c:chessboard){
            Arrays.fill(c,'.');
        }

        backtracking(0,n,chessboard);
        return result;
    }

    private List Array2List(char[][] chessboard){
        List<String> list = new ArrayList<>();

        for(char[] c:chessboard){
            list.add(String.copyValueOf(c));
        }

        return list;
    }

    private void backtracking(int row,int n,char[][] chessboard){
        if(row == n){
            result.add(Array2List(chessboard));
            return;
        }
        for(int col = 0;col < n;col++){
            if(isValid(row,col,n,chessboard)){
                chessboard[row][col] = 'Q';
                backtracking(row+1,n,chessboard);
                chessboard[row][col] = '.';
            }
        }
    }
    private boolean isValid(int row,int col,int n,char[][] chessboard){
        for(int i=0;i<row;i++){
            if(chessboard[i][col]=='Q'){
                return false;
            }
        }
        for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
            if(chessboard[i][j]=='Q'){
                return false;
            }
        }
        for(int i=row-1,j=col+1;i>=0&&j<=n-1;i--,j++){
            if(chessboard[i][j]=='Q'){
                return false;
            }
        }
        return true;
    }

}

解数独 LeetCode 37

题目链接:[LeetCode 37 - 困难]

思路

    int iIndex = (row / 3) *3;
    int jIndex = (col / 3) *3;

回溯:

class Solution {
    public void solveSudoku(char[][] board) {
        backtracking(board);
    }
    private boolean backtracking(char[][] board){
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                if (board[i][j] != '.'){ 
                    continue;
                }
                for(char num='1';num<='9';num++)
                    if(isValid(i,j,board,num)){
                        board[i][j] = num;
                        if(backtracking(board)){
                            return true;
                        }
                        board[i][j] = '.';
                    }
                return false;
            }
        }
        return true;
    }

    private boolean isValid(int row,int col,char[][] board,char num){
        for(int i=0;i<9;i++){
            if(board[i][col]==num){
                return false;
            }
        }
        for(int j=0;j<9;j++){
            if(board[row][j]==num){
                return false;
            }
        }
        int iIndex = (row / 3) *3;
        int jIndex = (col / 3) *3;
        for(int i=iIndex;i<iIndex+3;i++){
            for(int j=jIndex;j<jIndex+3;j++){
                if(board[i][j]==num){
                    return false;
                }
            }
        }
        return true;
    }
}

非递减子序列 LeetCode 491

题目链接:[LeetCode 491 - 中等]

思路

使用HashSet去重。

回溯:

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new LinkedList<>();
    public List<List<Integer>> findSubsequences(int[] nums) {
        backtracking(nums,0);
        return result;
    }
    private void backtracking(int[] nums,int index){
        if(path.size()>=2){
            result.add(new ArrayList(path));
        }
        HashSet<Integer> hs = new HashSet<>();
        for(int i=index;i<nums.length;i++){
            if(!path.isEmpty()&&path.getLast()>nums[i] || hs.contains(nums[i])){
                continue;
            }
            hs.add(nums[i]);
            path.add(nums[i]);
            backtracking(nums,i+1);
            path.removeLast();
        }
    }
}

重新安排行程 LeetCode 332

题目链接:[LeetCode 332 - 困难]

思路

所想的思路会导致80例超时

回溯:

class Solution {
    Deque<String> res;
    Map<String,Map<String,Integer>> map;
    private boolean backTracking(int ticketNum){
        if(res.size()==ticketNum+1){
            return true;
        }
        String last = res.getLast();
        if(map.containsKey(last)){
            for(Map.Entry<String,Integer> target:map.get(last).entrySet()){
                int count = target.getValue();
                if(count>0){
                    res.add(target.getKey());
                    target.setValue(count-1);
                    if(backTracking(ticketNum))return true;
                    res.removeLast();
                    target.setValue(count);
                }
            }
        }
        return false;
    }
    public List<String> findItinerary(List<List<String>> tickets) {
        map = new HashMap<>();
        res = new LinkedList<>();
        for(List<String> t:tickets){
            Map<String,Integer> temp;
            if(map.containsKey(t.get(0))){
                temp = map.get(t.get(0));
                temp.put(t.get(1),temp.getOrDefault(t.get(1),0)+1);
            }else{
                temp = new TreeMap<>();
                temp.put(t.get(1),1);
            }
            map.put(t.get(0),temp);
        }
        res.add("JFK");
        backTracking(tickets.size());
        return new ArrayList<>(res);
    }
}