火柴拼正方形

题目要求

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

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

示例 1:

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

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

示例 2:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/matchsticks-to-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

回溯算法+贪心策略

首先我们判断数组元素的和是不是4的倍数,如果不是的话一定返回false。由于火柴不能折断,数组中某一元素大于正方形的边长(数组内元素和/4),那么也将返回false。

接下来我们使用回溯法来判断能否拼成正方形。这道题里面的回溯指的是把火柴放进不同的边里,这就相当于将火柴放入大小为4的数组某一维度中去。直到全部的火柴处理完为止。在处理过程中,如果摸一个边的大小已经超过了正方形的边长,就进行剪枝操作。

贪心算法在题目中应用于从大到小处理,速度会快很多。

public class Solution1 {
    public boolean makesquare(int[] nums) {
        int sum = 0;
        for(int num : nums)
            sum += num;
        if(sum == 0 || sum % 4 != 0)
            return false;
        int target = sum / 4;

        for(int num : nums)
            if(num > target)
                return false;
        //从大到小的回溯,效率更高
        Arrays.sort(nums);
        backtrack(nums.length - 1, nums, target, new int[4]);
        return ans;

    }
    boolean ans = false;
    void backtrack(int cur, int[] nums, int target, int[] temp) {
        if(ans) return;
        if(cur == -1) {
            for(int num : temp)
                if(num != target)
                    return;
            ans = true;
            return;
        }
        for(int i = 0; i < temp.length; i++) {
            int last = temp[i];
            temp[i] += nums[cur];
            if(temp[i] <= target)
                backtrack(cur - 1, nums, target, temp);
            temp[i] = last;
        }
    }
}

   转载规则


《火柴拼正方形》 cyyyys 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
唯一摩尔斯密码词 唯一摩尔斯密码词
题目要求国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: “a” 对应 “.-“, “b” 对应 “-…”, “c” 对应 “-.-.”, 等等。 为了方便,所有26个英文字母对应摩尔斯密码表如
2019-09-06
下一篇 
删除最外层括号 删除最外层括号
题目要求有效括号字符串为空 (“”)、”(“ + A + “)” 或 A + B,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。例如,””,”()”,”(())()” 和 “(()(()))” 都是有效的括号字符串。 如果有
2019-09-04
  目录