LeetCode 52 - N-Queen II


Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.

https://segmentfault.com/a/1190000003762668
We can use O(1) to detect is valid -> O(N^2)
https://leetcode.com/discuss/18411/accepted-java-solution
* don't need to actually place the queen, * instead, for each row, try to place without violation on * col/ diagonal1/ diagnol2. * trick: to detect whether 2 positions sit on the same diagnol: * if delta(col, row) equals, same diagnol1; * if sum(col, row) equals, same diagnal2. private final Set<Integer> occupiedCols = new HashSet<Integer>(); private final Set<Integer> occupiedDiag1s = new HashSet<Integer>(); private final Set<Integer> occupiedDiag2s = new HashSet<Integer>(); public int totalNQueens(int n) { return totalNQueensHelper(0, 0, n); } private int totalNQueensHelper(int row, int count, int n) { for (int col = 0; col < n; col++) { if (occupiedCols.contains(col)) continue; int diag1 = row - col; if (occupiedDiag1s.contains(diag1)) continue; int diag2 = row + col; if (occupiedDiag2s.contains(diag2)) continue; // we can now place a queen here if (row == n-1) count++; else { occupiedCols.add(col); occupiedDiag1s.add(diag1); occupiedDiag2s.add(diag2); count = totalNQueensHelper(row+1, count, n); // recover occupiedCols.remove(col); occupiedDiag1s.remove(diag1); occupiedDiag2s.remove(diag2); } } return count; }
https://discuss.leetcode.com/topic/26987/pretty-simple-java-solution/2
  Set<Integer> col = new HashSet<Integer>();
  Set<Integer> diag1 = new HashSet<Integer>();
  Set<Integer> diag2 = new HashSet<Integer>();

  public int totalNQueens(int n) {
    int[] res = new int[1];//\\
    helper(res,n,0);
    return res[0];
    
}
  public void helper(int[] res, int n, int row){
    if(row==n){
        res[0]++;
    }
    else{
        for(int i=0; i<n; i++){
            if(col.contains(i) || diag1.contains(i+row) || diag2.contains(row-i)) continue;
            else{
                col.add(i);
                diag1.add(i+row);
                diag2.add(row-i);
                helper(res,n,row+1);
                col.remove(i);
                diag1.remove(i+row);
                diag2.remove(row-i);
            }
         }
      }
   }

https://leetcode.com/discuss/18411/accepted-java-solution
https://leetcode.com/discuss/69603/easiest-java-solution-1ms-98-22%25
Start row by row, and loop through columns. At each decision point, skip unsafe positions by using three boolean arrays.
Start going back when we reach row n.
Just FYI, if using HashSet, running time will be at least 3 times slower!
    int count = 0;
    public int totalNQueens(int n) {
        boolean[] cols = new boolean[n];     // columns   |
        boolean[] d1 = new boolean[2 * n];   // diagonals \
        boolean[] d2 = new boolean[2 * n];   // diagonals /
        backtracking(0, cols, d1, d2, n);
        return count;
    }
    
    public void backtracking(int row, boolean[] cols, boolean[] d1, boolean []d2, int n) {
        if(row == n) count++;

        for(int col = 0; col < n; col++) {
            int id1 = col - row + n;
            int id2 = col + row;
            if(cols[col] || d1[id1] || d2[id2]) continue;
            
            cols[col] = true; d1[id1] = true; d2[id2] = true;
            backtracking(row + 1, cols, d1, d2, n);
            cols[col] = false; d1[id1] = false; d2[id2] = false;
        }
    }

int result = 0; public int totalNQueens(int n) { boolean[] column = new boolean[n]; boolean[] dia45 = new boolean[2 * n - 1]; boolean[] dia135 = new boolean[2 * n - 1]; helper(0, n, column, dia45, dia135); return result; } private void helper(int row, int n, boolean[] column, boolean[] dia45, boolean[] dia135) { if (row == n) { result++; return; } for (int col = 0; col < n; col++) { if (!column[col] && !dia45[col + row] && !dia135[n - 1- row + col]) { column[col] = dia45[col + row] = dia135[n - 1- row + col] = true; helper(row + 1, n, column, dia45, dia135); column[col] = dia45[col + row] = dia135[n - 1- row + col] = false; } } }
Just FYI, if using HashSet, running time will be at least 3 times slower!
int count = 0; public int totalNQueens(int n) { boolean[] cols = new boolean[n]; // columns | boolean[] d1 = new boolean[2 * n]; // diagonals \ boolean[] d2 = new boolean[2 * n]; // diagonals / backtracking(0, cols, d1, d2, n); return count; } public void backtracking(int row, boolean[] cols, boolean[] d1, boolean []d2, int n) { if(row == n) count++; for(int col = 0; col < n; col++) { int id1 = col - row + n; int id2 = col + row; if(cols[col] || d1[id1] || d2[id2]) continue; cols[col] = true; d1[id1] = true; d2[id2] = true; backtracking(row + 1, cols, d1, d2, n); cols[col] = false; d1[id1] = false; d2[id2] = false; } }
https://leetcode.com/discuss/6764/my-iterative-solution-for-reference-bit-wise-operation
https://discuss.leetcode.com/topic/38923/share-my-java-code-beats-97-83-run-times
    常规n-queens解法, 数答案个数.
    用column标记此行之前的哪些column已经放置了queen. 棋盘坐标(row, col)对应column的第col位(LSB --> MSB, 下同).
    用diag标记此位置之前的哪些主对角线已经放置了queen. 棋盘坐标(row, col)对应diag的第(n - 1 + row - col)位.
    用antiDiag标记此位置之前的哪些副对角线已经放置了queen. 棋盘坐标(row, col)对应antiDiag的第(row + col)位.
    int count = 0;    
    public int totalNQueens(int n) {
        dfs(0, n, 0, 0, 0);
        return count;
    }
    
    private void dfs(int row, int n, int column, int diag, int antiDiag) {
        if (row == n) {
            ++count;
            return;
        }
        for (int i = 0; i < n; ++i) {
            boolean isColSafe = ((1 << i) & column) == 0;
            boolean isDiagSafe = ((1 << (n - 1 + row - i)) & diag) == 0;
            boolean isAntiDiagSafe = ((1 << (row + i)) & antiDiag) == 0;
            if (isColSafe && isDiagSafe && isAntiDiagSafe) {
                dfs(row + 1, n, (1 << i) | column, (1 << (n - 1 + row - i)) | diag, (1 << (row + i)) | antiDiag);
            }
        }
    }
X. BitMap
https://leetcode.com/discuss/743/whats-your-solution
And a picture to illustrate how the bits projection works. enter image description here
/* backtrace program using bit-wise operation to speed up calculation. * 'limit' is all '1's. * 'h' is the bits all the queens vertically projected on a row. If h==limit, then it's done, answer++. * 'r' is the bits all the queens anti-diagonally projected on a row. * 'l' is the bits all the queens diagonally projected on a row. * h|r|l is all the occupied bits. Then pos = limit & (~(h|r|l)) is all the free positions. * p = pos & (-pos) gives the right most '1'. pos -= p means we will place a queen on this bit * represented by p. * 'h+p' means one more queue vertically projected on next row. * '(r+p)<<1' means one more queue anti-diagonally projected on next row. Because we are * moving to next row and the projection is skew from right to left, we have to * shift left one position after moved to next row. * '(l+p)>>1' means one more queue diagonally projected on next row. Because we are * moving to next row and the projection is skew from left to right, we have to * shift right one position after moved to next row. */ int totalNQueens(int n) { ans = 0; limit = (1<<n) - 1; dfs(0, 0, 0); return ans; } void dfs(int h, int r, int l) { if (h == limit) { ans++; return; } int pos = limit & (~(h|r|l)); while (pos) { int p = pos & (-pos); pos -= p; dfs(h+p, (r+p)<<1, (l+p)>>1); } } int ans, limit;
TODO: http://gregtrowbridge.com/a-bitwise-solution-to-the-n-queens-problem-in-javascript/
X. O(N^3)
http://www.jiuzhang.com/solutions/n-queens-ii/
    public static int sum;
    public int totalNQueens(int n) {
        sum = 0;
        int[] usedColumns = new int[n];
        placeQueen(usedColumns, 0);
        return sum;
    }
    public void placeQueen(int[] usedColumns, int row) {
        int n = usedColumns.length;
        
        if (row == n) {
            sum ++;
            return;
        }
        
        for (int i = 0; i < n; i++) {
            if (isValid(usedColumns, row, i)) {
                usedColumns[row] = i;
                placeQueen(usedColumns, row + 1);
            }
        }
    }
    public boolean isValid(int[] usedColumns, int row, int col) {
        for (int i = 0; i < row; i++) {
            if (usedColumns[i] == col) {
                return false;
            }
            if ((row - i) == Math.abs(col-usedColumns[i])) {
                return false;
            }
        }
        return true;
    }
https://leetcode.com/discuss/80764/collection-of-solutions-in-java

Eight Queens:Write an algorithm to print all ways of arranging eight queens on an 8x8 chess board
so that none of them share the same row, column, or diagonal. In this case, "diagonal" means all

diagonals, not just the two that bisect the board.
int GRID_SIZE = 8;

void placeQueens(int row, Integer[] columns, Arraylist<Integer[]> results) {
        if (row == GRID_SIZE) {//Found valid placement
                results.add(columns.clone());
        } else {
                for (int col= 0; col< GRID_SIZE; col++) {
                        if (checkValid(columns, row, col)) {
                                columns[row] = col; // Place queen
                                placeQueens(row + 1, columns, results);
                        }
                }
        }
}

/* Check if (rowl, column!) is a valid spot for a queen by checking if there is a
 * queen in the same column or diagonal. We don't need to check it for queens in
 * the same row because the calling placeQueen only attempts to place one queen at
 * a time. We know this row is empty. */
boolean checkValid(Integer[] columns, int rowl, int column1) {
        for (int row2 = 0; row2 < rowl; row2++) {
                int column2 = columns[row2];
                /* Check if (row2, column2) invalidates (rowl, columnl) as a
                 * queen spot. */

                /* Check if rows have a queen in the same column */
                if (columnl == column2) {
                        return false;
                }

                /* Check diagonals: if the distance between the columns equals the distance
                 * between the rows, then they're in the same diagonal. */
                int columnDistance = Math.abs(column2 - columnl);

                /* rowl > row2, so no need for abs */
                int rowDistance = rowl - row2;
                if (columnDistance == rowDistance) {
                        return false;
                }
        }
        return true;
}
Read full article from Just Codings: [LeetCode] N-Queens I && II

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts