• LeetCode 996 正方形数组的数目


    给定一个数组,将数组内数字重新排序,使得相邻的两个数字之和为完全平方数,求有多少种排列方法。如果两种方法每一位上的数字都相同,则视为一种。本题我的思路就是首先把每个数字看作节点,如果两个数字的和是完全平方数就可以连一条边,然后就可以开始回溯。在回溯的过程中,在当前状态下,如果选择的数字之前选择过,则不需要再选择,具体见代码。(第一次在力扣上写题解)

    class Solution {
    public:
        int vis[15],ans;//vis[i]表示第i个数字是否已经使用过
        int equ[13][13];//equ[i][j]=1表示第i个数和第j个数相等
        vector<int> G[13];//记录图中各节点的连接
        //now表示当前选择第now个节点,x表示当前节点是原数组的第x个数,end是数组大小
        void dfs(int now,int x,int end)
        {
            //记录当前选择的数字在之前是否使用过,如果使用过就可视为相同的情况,直接跳过。
            int trys[12]={0};
            //当前的数组顺序符合条件,答案加一
            if(now==end-1) 
            {
                ans++;
                return ;
            }
            //每次选择一个节点去进行回溯,第一个节点的选择没有限制
            if(now==-1){
                for(int i=0;i<end;i++)
                {
                    int ok=1;
                    //查询之前是否使用过相同的数字,有就跳过
                    for(int j=0;j<i;j++)
                    if(equ[i][j]&&trys[j])
                    {
                        ok=0;break;
                    }
                    if(ok)
                    { 
                        trys[i]=1;
                        vis[i]=1;
                        dfs(now+1,i,end);
                        vis[i]=0;
                    }
                }
            }
            //选择第now+1个节点,只能选择与now节点能组成完全平方数的数字
            else{
                for(int i=0;i<G[x].size();i++)
                if(!vis[G[x][i]])
                {
                    int ok=1;
                    for(int j=0;j<i;j++)
                    if(equ[G[x][i]][G[x][j]]&&trys[G[x][j]])
                    {
                        ok=0;break;
                    }
                    if(ok)
                    {
                        trys[G[x][i]]=1;
                        vis[G[x][i]]=1;
                        dfs(now+1,G[x][i],end);
                        vis[G[x][i]]=0;
                    }
                }
            }
    
        }
        int numSquarefulPerms(vector<int>& A) {
            int sz=A.size();
            int sum,t;
            for(int i=0;i<sz;i++)
                for(int j=i+1;j<sz;j++)
                {
                    if(A[i]==A[j]) equ[i][j]=equ[j][i]=1;
                    sum=A[i]+A[j];
                    t=sqrt(sum);
                    //如果两个数字加起来是完全平方数,就连一条线
                    if(t*t==sum)
                    {
                        G[i].push_back(j);
                        G[j].push_back(i);
                    }
                }
            ans=0;
            dfs(-1,-1,sz);
            return ans;
        }
    };
    
  • 相关阅读:
    配置PyCharm(背景色+字体大小+解释器选择)
    面向对象的三大特性(封装、继承、多态)
    hashlib模块
    logging模块
    Mac OSX系统、Linux、Windows命令行教程
    Python2和Python3的一些语法区别
    python——内置函数和lambda匿名函数
    python——异常处理
    SVN
    实体框架Entity Framework 4.1快速入门
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12878016.html
Copyright © 2020-2023  润新知