Leetcode 473.火柴拼正方形

火柴拼正方形

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

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

示例 1:

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

输出: true

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

示例 2:

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

输出: false

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

注意:

  1. 给定的火柴长度和在 0 到 10^9之间。
  2. 火柴数组的长度不超过15。

想象正方形的4条边是4个桶,将每个火柴棍回溯放置在每个桶中,放完N个后,检查4个桶中的长度和是否相同

优化剪枝:

1.N个火柴棍的总和对4取余是不是0,不是的话返回假

2.长度按照从大到小排序,先尝试长的,减少回溯的可能

3.每次放置时,每条边上不可放置超过总和1/4长度的火柴棍

 1 import java.util.Arrays;
 2 
 3 class Solution {
 4     public boolean makesquare(int[] nums) {
 5         if(nums.length<4) return false;
 6         int sum=0;
 7         for(int i=0;i<nums.length;i++) sum+=nums[i];
 8         if(sum%4!=0) return false;
 9         Arrays.sort(nums);
10         int[] bucket=new int[4];
11         return generate(0,nums,sum/4,bucket);
12     }
13 
14     public boolean generate(int i,int[] nums,int target,int[] bucket){
15         if(i==nums.length) return bucket[0]==target&&bucket[1]==target&&bucket[2]==target&&bucket[3]==target;
16         for(int j=0;j<4;j++){
17             if(bucket[j]+nums[i]>target) continue;
18             bucket[j]+=nums[i];
19             if(generate(i+1,nums,target,bucket)) return true;
20             bucket[j]-=nums[i];
21         }
22         return false;
23     }
24 }
原文地址:https://www.cnblogs.com/kexinxin/p/10280234.html