leetcode-回溯-51


题面

image-20201226190722892

重点

  • 遇到难题时,一遍写注释一边写代码是一个很好的习惯

  • 细节决定成败,由于写程序时下标选择从1开始,定义数组时潜意识里认为下标从0开始,然后就有了如下惨案:

    image-20201226185237426
  • 更惨的是,上面的错误提示,压根就没涉及到数组越界,它会将我引入错误的调试过程,我以为不该在递归过程中用string类型,然后改了又改。。。

  • 我之所以坚定的认为不该在递归过程中用string类型,是因为我在本地code_blocks加上main函数运行这段程序,n=4、n=8,都能给出正确结果(这就是g++的坑人之处

  • g++不检查数组越界,哪怕数组再怎么越界,越到操作系统内核了,编译器也不管,照样编译通过,根据网上的说法,code_blocks、VC++、VS里都出现过这种情况。

  • ”C语言非常重视运行时的效率,所以没有进行数组越界检查,而C++继承了C的效率要求,自然也不做数组越界检查。(检查数据越界,编译器就必须在生成的目标代码中加入额外的代码用于程序运行时检测下标是否越界,这就会导致程序的运行速度下降)”

    摘自https://blog.csdn.net/weixin_40327927/article/details/103445893

  • 数组越界在运行的时候可能也不会表现出来,这就很可怕了,如果是火箭发射系统,发射前都运行的好好的,发射之后,嘭,炸了,原因是之前数组越界的时候没有覆盖到核心代码,而这次数组越界越到核心代码上去了,然后整个系统的逻辑全都混乱了。

    详见下面两份实验代码:

    image-20201226190413021 image-20201226190445651

源代码(回溯法,记住这个模板)

class Solution
{
public:
    void ge(int index,int n, vector> &result,vector& temp,bool hashTable[],int P[])
    {
        if(index==n+1)
        {
            result.push_back(temp);
            return;
        }
        //当前处在第index行,i从第1列到第n列进行枚举,看看这一列是否满足要求
        for(int i=1; i<=n; i++)
        {
            //第i列还没有被访问过
            if(!hashTable[i])
            {
                int pre = index;
                //j表示之前的行数,P[j]表示第j行皇后在第P[j]列
                int j = 1;
                bool flag = true;
                while(j
> solveNQueens(int n)
    {
        vector> result;
        vector temp;
        bool hashTable[n+2];
        for(int i=0; i