如何获得 N 个皇后验证器的更好时间复杂度

Posted

技术标签:

【中文标题】如何获得 N 个皇后验证器的更好时间复杂度【英文标题】:How to get better time complexity of N queens validator 【发布时间】:2021-12-01 11:46:43 【问题描述】:

我们如何降低 NxN 皇后矩阵验证器解决方案的时间复杂度? 当我检查矩阵的每一行、每一列和每个对角线时,我就有了这个解决方案。 如果每一行和每一列都恰好有 1 个皇后,并且矩阵不超过 1 个皇后,则输出为真。 此解决方案有效,但我认为这是蛮力。

   public static boolean solveMatrix(int[][] matrix) 

        int row, col;
        int rowCount = matrix.length;
        int columnCount = matrix[0].length;
        int counter = 0;

        // Checking if there is 1 queen per row
        for (int i = 0; i < 8; i++) 
            counter = 0;
            for (int j = 0; j < 8; j++) 

                if (matrix[i][j] == 1) 

                    counter++;
                

            
            if (counter != 1) 

                return false;
            

        
// Checking if there is 1 queen per column
        for (int i = 0; i < 8; i++) 
            counter = 0;
            for (int j = 0; j < 8; j++) 

                if (matrix[j][i] == 1) 

                    counter++;
                

            
            if (counter != 1) 

                return false;
            

        
        // Checking first side diagonals
        for (int k = 0; k < rowCount; k++) 
            counter = 0;
            for (row = k, col = 0; row >= 0 && col < columnCount; row--, col++) 
                if (matrix[row][col] == 1) 
                    counter++;
                
            
            if (counter > 1) 
                return false;
            
        
    // Checking first side diagonals
        for (int k = 1; k < columnCount; k++) 
            counter = 0;
            for (row = rowCount - 1, col = k; row >= 0 && col < columnCount; row--, col++) 
                if (matrix[row][col] == 1) 
                    counter++;
                
            
            if (counter > 1) 
                return false;
            
        
        // Checking second side diagonals
        for (int k = rowCount - 1; k >= 0; k--) 
            counter = 0;
            for (row = k, col = columnCount - 1; row >= 0 && col >= 0; row--, col--) 

                if (matrix[row][col] == 1) 
                    counter++;
                

            
            if (counter > 1) 
                return false;
            
        
// Checking second side diagonals
        for (int k = rowCount - 1; k >= 0; k--) 
            counter = 0;
            for (row = k, col = columnCount - 1; row >= 0 && col >= 0; row--, col--) 

                if (matrix[row][col] == 1) 
                    counter++;
                

            
            if (counter > 1) 
                return false;
            
        

        return true;

    

【问题讨论】:

你可能会发现一些想法here。 你方法的时间复杂度是O(n^2)。由于您将输入作为 NxN 数组接收,因此无法改进。您可以获得效率提升,但时间复杂度仍将是O(n^2)。如果您收到的输入是 N 个职位的列表,那么您可以在 O(n) 中验证它,但不能使用当前输入表单。 【参考方案1】:

您需要使用 4 个哈希图,一个用于列,一个用于行,一个用于从左到右的对角线,一个用于从右到左的对角线。

现在,只对行和列执行一个嵌套循环。当你找到一个女王时,请执行以下 4 个步骤:

    检查该行索引处的行哈希映射中是否有皇后。如果没有,请添加行索引。如果已经有,则返回 false。 检查在 col 索引处是否存在 col hashmap 中的皇后。如果没有,请添加 col 索引。如果已经有,则返回 false。 检查从左到右的对角线是否有一个从左到右对角线哈希图中的皇后并采取相应的行动。请注意,每个从左到右的对角线 rowIndex-columnIndex 始终相同。 检查从右到左的对角线是否有一个皇后在从右到左的对角线哈希图中并采取相应措施。请注意,从右到左的每条对角线 rowIndex+columnIndex 始终相同。

如果成功完成了上面的嵌套循环,则说明板子有效。返回真。

此算法在O(n^2) 中运行,其中n 是方阵一侧的长度。

它在矩阵n 的边长上具有线性空间复杂度,因为我们最多使用 4 个哈希图,每个 n 元素。

【讨论】:

以上是关于如何获得 N 个皇后验证器的更好时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

回溯经典n皇后的时间复杂度分析

暴力穷举和回溯法(八皇后问题)

搜索八皇后

#yyds干货盘点# 面试必刷TOP101:N皇后问题

求教C语言回溯法写出八皇后问题的92种解

如何为回溯算法获得更严格的界限?