leetcode 473. 火柴拼正方形(DFS,回溯)

题目链接

473. 火柴拼正方形

题意

给定一串数,判断这串数字能不能拼接成为正方形

思路

DFS,但是不能每次从从序列开始往下搜索,因为这样无法做到四个边覆盖不同位置的值,比如输入是(5,5,5,5,4,4,4,4,3,3,3,3)这种情况
以四条边分类讨论,每次加入序列的值,最后判断四条边的结果是否相等

其次注意剪枝:

  • 首先将序列逆序排列,尤其遇到(1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4....),如果正着搜索那么一定会超时
  • 每一轮检查每条边加上序列的值,得到的结果如果大于边长,那么直接剪枝
class Solution {
public:
    int avr=-1;
    bool dfs(vector<int> nums,int pos,int cnt[4]){
        if(pos==-1){
            return cnt[0]==cnt[1] && cnt[1]==cnt[2] && cnt[2]==cnt[3] && cnt[3]==avr;
        }

        //对每一个段的值进行统计
        for(int i=0;i<4;i++){//对每一段分别统计
            if(cnt[i]+nums[pos]>avr) continue;//剪枝

            cnt[i]+=nums[pos];
            if(dfs(nums,pos-1,cnt)) return true;

            cnt[i]-=nums[pos];
        }

        return false;
    }
    bool makesquare(vector<int>& nums) {
        int sum=0;
        for(int num:nums) sum+=num;
        if(sum%4!=0) return false;
        if(!nums.size()) return false;//特判一下[]

        avr=sum/4;
        sum=0;
        //排序一下,减少调用次数,从大到小调用,类似于剪枝
        sort(nums.begin(),nums.end());
        int cnt[4]={0};

        return dfs(nums,nums.size()-1,cnt);

    }

    // bool dfs(vector<int> nums,int sum,int pos,int cnt){ //记录四条边的长度
    //     if(sum>avr) return false;
    //     if(sum==avr) {
    //         cnt++;
    //         sum=0;
    //     }
    //     if(pos==nums.size()){
    //         if(cnt==4) return true;
    //         else return false;
    //     }
    //     for(int i=pos;i<nums.size();i++){
    //         sum+=nums[i];
    //         if(dfs(nums,sum,i+1,cnt)) return true;//只能判断连续的值
    //         sum-=nums[i];
    //     }

    //     return false;
    // }
    // bool dfs(vector<int> nums,vector<int> tmp,int pos){
    //     if(tmp.size() && tmp[tmp.size()-1]>avr) return false;
    //     if(tmp.size()>4) return false;
    //     if(tmp.size()==4){
    //         if(tmp[0]==tmp[1] && tmp[1]==tmp[2] && tmp[2]==tmp[3] &&tmp[0]==avr) return true;
    //         return false;
    //     }

    //     for(int i=pos;i<nums.size();i++){//顺序不是连在一起的
    //         tmp.push_back()
    //     }

    //     return false;
    // }
    // bool dfs(vector<int> nums,int pos,vector<int> cnt(4,0)){//每一部分的和
};
posted @ 2020-11-21 16:22  xzhws  阅读(191)  评论(0编辑  收藏  举报