Leecode刷题C语言之N皇后②

执行结果:通过

执行用时和内存消耗如下:

复制代码
struct hashTable {
    int key;
    UT_hash_handle hh;
};

struct hashTable* find(struct hashTable** hashtable, int ikey) {
    struct hashTable* tmp = NULL;
    HASH_FIND_INT(*hashtable, &ikey, tmp);
    return tmp;
}

void insert(struct hashTable** hashtable, int ikey) {
    struct hashTable* tmp = NULL;
    HASH_FIND_INT(*hashtable, &ikey, tmp);
    if (tmp == NULL) {
        tmp = malloc(sizeof(struct hashTable));
        tmp->key = ikey;
        HASH_ADD_INT(*hashtable, key, tmp);
    }
}

void erase(struct hashTable** hashtable, int ikey) {
    struct hashTable* tmp = NULL;
    HASH_FIND_INT(*hashtable, &ikey, tmp);
    if (tmp != NULL) {
        HASH_DEL(*hashtable, tmp);
        free(tmp);
    }
}

struct hashTable *columns, *diagonals1, *diagonals2;

int backtrack(int n, int row) {
    if (row == n) {
        return 1;
    } else {
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (find(&columns, i) != NULL) {
                continue;
            }
            int diagonal1 = row - i;
            if (find(&diagonals1, diagonal1) != NULL) {
                continue;
            }
            int diagonal2 = row + i;
            if (find(&diagonals2, diagonal2) != NULL) {
                continue;
            }
            insert(&columns, i);
            insert(&diagonals1, diagonal1);
            insert(&diagonals2, diagonal2);
            count += backtrack(n, row + 1);
            erase(&columns, i);
            erase(&diagonals1, diagonal1);
            erase(&diagonals2, diagonal2);
        }
        return count;
    }
}

int totalNQueens(int n) {
    columns = diagonals1 = diagonals2 = NULL;
    return backtrack(n, 0);
}

解题思路:

这段代码是用来解决经典的N皇后问题的,它利用了哈希表来高效地存储和查询在N皇后问题中已经被占用的列、主对角线和副对角线的信息。下面是代码的详细思路:

数据结构定义

  1. 哈希表结构
    • struct hashTable:定义了一个哈希表节点,包含一个整型key用于存储列、主对角线或副对角线的标识符,以及一个UT_hash_handle hh,这是uthash库用来管理哈希表节点的内部字段。

哈希表操作函数

  1. 查找函数find
    • 输入:指向哈希表头指针的指针hashtable和要查找的键ikey
    • 功能:在哈希表中查找键为ikey的节点。
    • 输出:返回找到的节点指针,如果未找到则返回NULL
  2. 插入函数insert
    • 输入:指向哈希表头指针的指针hashtable和要插入的键ikey
    • 功能:如果哈希表中不存在键为ikey的节点,则创建一个新节点并插入到哈希表中。
    • 输出:无。
  3. 删除函数erase
    • 输入:指向哈希表头指针的指针hashtable和要删除的键ikey
    • 功能:从哈希表中删除键为ikey的节点,并释放该节点的内存。
    • 输出:无。

解决N皇后问题的函数

  1. 回溯函数backtrack
    • 输入:棋盘的大小n和当前正在放置皇后的行row
    • 功能:尝试在每一行放置一个皇后,并递归地尝试放置下一行的皇后,直到所有行都成功放置了皇后(即找到一个解),或者所有可能的放置方式都尝试完毕。
    • 辅助数据结构:使用三个哈希表columnsdiagonals1diagonals2分别记录被占用的列、主对角线和副对角线的标识符。
    • 输出:返回找到的解的数量。
  2. 主函数totalNQueens
    • 输入:棋盘的大小n
    • 功能:初始化三个哈希表,并调用回溯函数backtrack开始求解。
    • 输出:返回N皇后问题的解的总数。

解决方案思路

  • 初始化:创建三个哈希表来跟踪哪些列、主对角线和副对角线已被占用。
  • 回溯 :对于每一行,尝试在该行的每一列放置一个皇后。
    • 检查当前列是否已被占用。
    • 计算当前位置所在的主对角线和副对角线的标识符,并检查它们是否已被占用。
    • 如果当前位置可行(即所在列、主对角线和副对角线都未被占用),则标记这些位置为已占用,并递归地尝试放置下一行的皇后。
    • 如果成功放置了所有行的皇后,则找到一个解,增加解计数器。
    • 回溯时,撤销对当前位置及其所在列、主对角线和副对角线的占用标记。
  • 结果:通过回溯所有可能的放置方式,最终得到N皇后问题的解的总数。
相关推荐
RaymondZhao3433 分钟前
【全面推导】策略梯度算法:公式、偏差方差与进化
人工智能·深度学习·算法·机器学习·chatgpt
zhangfeng113342 分钟前
DBSCAN算法详解和参数优化,基于密度的空间聚类算法,特别擅长处理不规则形状的聚类和噪声数据
算法·机器学习·聚类
啊阿狸不会拉杆2 小时前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
小学生的信奥之路2 小时前
洛谷P3817题解:贪心算法解决糖果分配问题
c++·算法·贪心算法
你知道网上冲浪吗3 小时前
【原创理论】Stochastic Coupled Dyadic System (SCDS):一个用于两性关系动力学建模的随机耦合系统框架
python·算法·数学建模·数值分析
地平线开发者4 小时前
征程 6 | PTQ 精度调优辅助代码,总有你用得上的
算法·自动驾驶
Tisfy5 小时前
LeetCode 837.新 21 点:动态规划+滑动窗口
数学·算法·leetcode·动态规划·dp·滑动窗口·概率
CoovallyAIHub5 小时前
为高空安全上双保险!无人机AI护航,YOLOv5秒判安全带,守护施工生命线
深度学习·算法·计算机视觉
huangzixuan10075 小时前
08.18总结
算法·深度优先·图论
逆向菜鸟5 小时前
【摧毁比特币】椭圆曲线象限细分求k-陈墨仙
python·算法