天天看点

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      

心得体会