DFS--排列组合(回溯)996. 正方形数组的数目

996. 正方形数组的数目

难度困难30

给定一个非负整数数组 A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组。

返回 A 的正方形排列的数目。两个排列 A1 和 A2 不同的充要条件是存在某个索引 i,使得 A1[i] != A2[i]。

 

示例 1:

输入:[1,17,8]
输出:2
解释:
[1,8,17] 和 [17,8,1] 都是有效的排列。

示例 2:

输入:[2,2,2]
输出:1

 

提示:

  1. 1 <= A.length <= 12
  2. 0 <= A[i] <= 1e9
class Solution:
    def numSquarefulPerms(self, A: List[int]) -> int:
        self.res = 0
        num = len(A)
        if num == 0:
            return 0
        elif num == 1:
            return 1 if math.sqrt(A[0]) % 1 == 0 else 0
        # 给数组A从小到大排序
        A.sort()
        Visited = [False for _ in A]
        def _judge(a : int, b : int) -> bool:
            return True if math.sqrt(a + b) % 1 == 0 else False
        def _trace_back(depth : int, path : List[int], Visited : List[bool]):
            # 剪枝
            if depth > 1 and not _judge(path[-1], path[-2]):
                return
            # 递归出口返回结果
            if depth == num:
                self.res += 1
                return
            for i in range(num):
                if not Visited[i]:
                    if i > 0 and A[i] == A[i - 1] and not Visited[i - 1]:
                        continue
                    Visited[i] = True
                    path.append(A[i])
                    _trace_back(depth + 1,path,Visited)
                    path.pop()
                    Visited[i] = False
        _trace_back(0,[],Visited)
        return self.res

心得体会

        1.这是一道经典的回溯问题,不同于模板,本题依据具体的题意加入了剪枝的判断条件。当当前路径列表内倒数第一项与倒数第二项相加和不是平方数时直接返回停止迭代。

        2.回溯问题要注意的一点就是剪枝条件要放在递归出口前面!!!!!

        3.python的函数传递只要形参是列表,字典,tuple等可以改变的容器都是引用传值!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值