1
+
2
+ /**
3
+ * Return an array of arrays of size *returnSize.
4
+ * The sizes of the arrays are returned as *returnColumnSizes array.
5
+ * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
6
+ */
7
+
8
+
9
+ // An array to traverse all 4 diagonal directions on the chessboard.
10
+ int diagonals [][2 ] = {{1 , -1 }, {1 , 1 }, {-1 , 1 }, {-1 , -1 }};
11
+
12
+ // A result-stack to store all possible n-queen solutions at a time on a stack during backtracking.
13
+ struct result_stack {
14
+ char * * chessboard ;
15
+ struct result_stack * next ;
16
+ };
17
+
18
+ // A Node() function to create a new stack node.
19
+ struct result_stack * Node () {
20
+ struct result_stack * node = (struct result_stack * )malloc (sizeof (struct result_stack ));
21
+ node -> next = NULL ;
22
+ node -> chessboard = NULL ;
23
+ return node ;
24
+ }
25
+
26
+ // toggle_queen() function to place and remove any queen on the chessboard by passing in the toggle parameter as 1 or -1.
27
+ // toggle == 1 to place a queen at (row, col) on the chessboard. Similarly toggle == -1 to remove a queen from the board.
28
+ void toggle_queen (char * * chessboard , int n , int row , int col , char toggle ) {
29
+
30
+ for (int i = 0 ; i < n ; i ++ ) chessboard [row ][i ] += toggle ;
31
+ for (int j = 0 ; j < n ; j ++ ) chessboard [j ][col ] += toggle ;
32
+
33
+ for (int x ; x < 4 ; x ++ ) {
34
+ int i = row + diagonals [x ][0 ];
35
+ int j = col + diagonals [x ][1 ];
36
+ while (i >= 0 && i < n && j >= 0 && j < n ) {
37
+ chessboard [i ][j ] += toggle ;
38
+ i += diagonals [x ][0 ];
39
+ j += diagonals [x ][1 ];
40
+ }
41
+ }
42
+ chessboard [row ][col ] -= 3 * toggle ;
43
+ }
44
+
45
+ // copy_board() function to copy each possible solution from the chessboard during backtracking.
46
+ char * * copy_board (char * * chessboard , int n ) {
47
+
48
+ char * * copy = (char * * )malloc (n * sizeof (char * ));
49
+ for (int i = 0 ; i < n ; i ++ ) {
50
+ copy [i ] = (char * )malloc ((n + 1 ) * sizeof (char ));
51
+ for (int j = 0 ; j < n ; j ++ ) {
52
+ chessboard [i ][j ] == -1 ? (copy [i ][j ] = 'Q' ) : (copy [i ][j ] = '.' );
53
+ }
54
+ copy [i ][n ] = '\0' ;
55
+ }
56
+ return copy ;
57
+ }
58
+
59
+ // Recursive backtracking method to go through all possible queen placements on the chessboard.
60
+ int backtrack (struct result_stack * stack , char * * chessboard , int n , int row ) {
61
+
62
+ if (row == n ) {
63
+ // Push the solution to the stack.
64
+ struct result_stack * node = Node (); // create a new stack node for a solution.
65
+ node -> chessboard = copy_board (chessboard , n );
66
+ node -> next = stack -> next ;
67
+ stack -> next = node ;
68
+ return 1 ;
69
+ }
70
+
71
+ int result_size = 0 ;
72
+ for (int col = 0 ; col < n ; col ++ ) {
73
+ if (chessboard [row ][col ] == 0 ) {
74
+ // Place the queen with toggle = 1.
75
+ toggle_queen (chessboard , n , row , col , 1 );
76
+ result_size += backtrack (stack , chessboard , n , row + 1 );
77
+ // Backtrack by removing the queen with toggle = -1.
78
+ toggle_queen (chessboard , n , row , col , -1 );
79
+ }
80
+ }
81
+ return result_size ;
82
+ }
83
+
84
+
85
+ char * * * solveNQueens (int n , int * returnSize , int * * returnColumnSizes ){
86
+
87
+ // Create a N x N chessboard for checking all possible queen placement scenarios.
88
+ char * * chessboard = (char * * )malloc (n * sizeof (char * ));
89
+ for (int i = 0 ; i < n ; i ++ ) {
90
+ chessboard [i ] = (char * )malloc (n * sizeof (char ));
91
+ for (int j = 0 ; j < n ; j ++ ) {
92
+ chessboard [i ][j ] = 0 ;
93
+ }
94
+ }
95
+
96
+ // Create an empty stack to collect all possible n-queen solutions during backtracking.
97
+ struct result_stack * stack = Node ();
98
+
99
+ // The Backtrack() method will find all possible solutions and stores them on the stack.
100
+ // Then returns the total size of the result, which is the total number of possible n-queen solutions.
101
+ * returnSize = backtrack (stack , chessboard , n , 0 );
102
+
103
+ // prepare the result array using the *returnSize obtained from backtracking.
104
+ char * * * result = (char * * * )malloc (* returnSize * sizeof (char * * ));
105
+ * returnColumnSizes = (int * )malloc (* returnSize * sizeof (int ));
106
+
107
+ // Pop every n-queen solution from the stack and assign them to the result array.
108
+ for (int i = 0 ; i < * returnSize ; i ++ ) {
109
+ returnColumnSizes [0 ][i ] = n ;
110
+ result [i ] = stack -> next -> chessboard ;
111
+ struct result_stack * deletenode = stack -> next ;
112
+ stack -> next = stack -> next -> next ;
113
+ // free up each stack node after every solution.
114
+ free (deletenode );
115
+ }
116
+ //free up the stack.
117
+ free (stack );
118
+
119
+ // free up the chessboard.
120
+ for (int row = 0 ; row < n ; row ++ ) {
121
+ free (chessboard [row ]);
122
+ }
123
+ free (chessboard );
124
+
125
+ return result ;
126
+ }
0 commit comments