[leetcode 473] 火柴拼正方形

还记得童话《卖火柴的小女孩》吗?现在,你知道小女孩有多少根火柴,请找出一种能使用所有火柴拼成一个正方形的方法。不能折断火柴,可以把火柴连接起来,并且每根火柴都要用到。

输入为小女孩拥有火柴的数目,每根火柴用其长度表示。输出即为是否能用所有的火柴拼成正方形。

示例 1:

输入: [1,1,2,2,2]
输出: true

解释: 能拼成一个边长为2的正方形,每边两根火柴。
示例 2:

输入: [3,3,3,3,4]
输出: false

解释: 不能用所有火柴拼成一个正方形。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/matchsticks-to-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
private static boolean generate(int[] nums) {
        if(nums.length < 4)
            return false;
        int tempSum = 0;
        for(int i=0; i<nums.length; i++) {
            tempSum += nums[i];
        }
        if(tempSum%4 != 0)
            return false;
        int target = tempSum/4;
        List<Integer> okSubset = new ArrayList<>();
        List<Integer> okHalf = new ArrayList<>();
        int all = 1<<nums.length;
        for(int i=1; i<all; i++) {
            int sum = 0;
            int val = 0;
            for(int j=0; j<nums.length; j++) {
                if((val = (i&(1<<j))) > 0) {
                    sum += nums[j];
                }
            }
            //生成所有符合 target 的集合
            if(sum == target) {
                okSubset.add(i);
            }
        }
        for(Integer i: okSubset)
            System.out.println(i);
        //{1, 1, 2, 4, 3, 2, 2, 1}
        //选取两边:每个集合包含的边不同,如 {1,1,2}=7(2的0次方,2的一次方...) {4}=8,位与为0
        for(int i=0; i<okSubset.size(); i++) {
            for(int j=i+1; j<okSubset.size(); j++) {
                if((okSubset.get(i)&okSubset.get(j)) == 0) {
                    okHalf.add((okSubset.get(i)|okSubset.get(j)));
                }
            }
        }
        //选取四边
        for(int i=0; i<okHalf.size(); i++) {
            for(int j=i+1; j<okHalf.size(); j++) {
                if((okHalf.get(i)&okHalf.get(j)) == 0) {
                    return true;
                }
            }
        }
        return false;
}
//数组降序 i数组的位置,target = sum/4,buckets 4个装数据的桶
private static boolean generate(int i, int[] nums, int target, int[] buckets) {
        if(i >= nums.length) {
            return buckets[0] == target && buckets[1] == target
                    && buckets[2] == target && buckets[3] == target;
        }
        for(int j=0; j<4; j++) {
            if(buckets[j]+nums[i] > target) {
                continue;
            }
            buckets[j] += nums[i];
            if(generate(i+1, nums, target, buckets)) {
                return true;
            }
            buckets[j] -= nums[i];
        }
        return false;
    }
}

你可能感兴趣的:(leetcode,搜素)