这个题解采用了深度优先搜索(DFS) + 回溯 + 位掩码的方法。首先,对数组进行排序,以便后续处理重复元素。然后,使用一个位掩码来表示当前哪些元素已经被选中。对于每一个可能的元素,如果它和前一个元素相同,并且前一个元素没有被选中,则跳过,以避免重复排列。接着,检查当前选中的元素和前一个元素的和是否是完全平方数,如果是,则继续递归搜索下一个元素。当所有元素都被选中时,找到了一个有效的排列,返回1。最后,返回所有有效排列的总数。
时间复杂度: O(n!)
空间复杂度: O(n)
class Solution:
def numSquarefulPerms(self, nums: List[int]) -> int:
n = len(nums)
nums.sort()
vis = [False] * n
def dfs(pre, mask):
if mask == (1 << n) - 1:
return 1
ans = 0
for i in range(n):
if (mask >> i) & 1:
continue
if i > 0 and nums[i] == nums[i - 1] and not vis[i - 1]:
continue
num = nums[i] + pre
if mask == 0 or (isqrt(num) ** 2 == num):
vis[i] = True
ans += dfs(nums[i], mask | (1 << i))
vis[i] = False
return ans
return dfs(-1, 0)