LeetCode 996. 正方形数组的数目 (回溯、结果去重、等价情况剪枝)

正方形数组的数目

思路:
回溯题基本写法。

  • multiset<int>去记录数字的使用情况。
  • set<vector<int>>去重。
  • 剪枝:虽然数字可以重复使用(如果有的话),但是每一层的数字不应出现重复枚举。
    比如:
    2 2 2 2 2
    每一层都应该放只能放2,而不是对2这个数字进行多次搜索。
class Solution {
public:
    multiset<int> nums;
    set<vector<int>> res;
    int len ;
    int numSquarefulPerms(vector<int>& A) {
        len = A.size();
        for(int x:A){
            nums.insert(x);
        }
        vector<int> list;
        dfs(0,list,A);
        return res.size();
    }
    void dfs(int dpt,vector<int> &list,vector<int>& A){
        if(dpt == len){
            res.insert(list);
            return;
        }
        unordered_set<int> optional;
        for(int x:A){
            if(nums.count(x)){
                if( dpt<1 || check(x+list[dpt-1])){
                    optional.insert(x);
                }
            }
        }
        for(unordered_set<int>::iterator it=optional.begin();it!=optional.end();it++){
            int x = *it;
            list.push_back(x);
            nums.erase(nums.find(x));
            dfs(dpt+1,list,A);
            list.pop_back();
            nums.insert(x);
        }
    }

    bool check(int x){
        int r = int(sqrt(x)+0.5);
        return x == r*r;
    }
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章