题目解析
一个数组,需要每两个相邻的数之和是完美平方,完美平方就是它们的和开方后是整数,需要找到所有满足条件的排列。
例子如下:
1 2 3
| 输入: [1,17,8] 输出: 2 解释: [1,8,17] 和 [17,8,1] 是正确的排列。比如[1,8,17],1+8=9是完美平方,8+17也是完美平方
|
方法
这里的思路是暴力得到所有的排列,在递归过程中使用if (can(A, start))
剪掉不能与前一个元素构成完美平方的元素,使用unordered_set<string>
去除重复的排列。因为只会遍历成功的节点,最坏情况下时间复杂度O(n!),因为剪枝,所以运行时间还行,4ms跑完。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class Solution { public: int numSquarefulPerms(vector<int>& A) { helper(A, 0); return result; } void helper(vector<int> &A, int start) { if (start == A.size()) { ostringstream oss; copy(A.begin(), A.end()-1,ostream_iterator<int>(oss, ",")); string per = oss.str(); if (has.find(per) != has.end()) return; has.insert(per); result++; return; } for (int i = start; i < A.size(); i++) { if (i != start && A[i] == A[start]) continue; if (i != start && i+1 < A.size() && A[i] == A[i+1]) continue; swap(A[i], A[start]); if (can(A, start)) { helper(A, start+1); } swap(A[i], A[start]); } } bool can(vector<int> &A, int start){ if (start > 0) { int y=(int)sqrt(A[start] + A[start-1]); if (y*y != (A[start] + A[start-1])) return false; } return true; } unordered_set<string> has; int result = 0; };
|