LeetCode刷题实战473:火柴拼正方形

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 火柴拼正方形,我们先来看题面:

https://leetcode-cn.com/problems/matchsticks-to-square/

You are given an integer array matchsticks where matchsticks[i] is the length of the ith matchstick. You want to use all the matchsticks to make one square. You should not break any stick, but you can link them up, and each matchstick must be used exactly one time.

Return true if you can make this square and false otherwise.

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

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

示例                         

示例 1:
输入: [1,1,2,2,2]
输出: true
解释: 能拼成一个边长为2的正方形,每边两根火柴。

示例 2:
输入: [3,3,3,3,4]
输出: false
解释: 不能用所有火柴拼成一个正方形。

解题

https://www.jianshu.com/p/f95eaadaa98c

首先判断什么情况下不能形成正方形。什么情况可以。

如果边数少于4跟边数不是4的倍数。肯定不能形成正方形

首先我们一边一边放火材。如果超过边长的话,就回溯。一直到每个边都刚好摆成正方形

就无脑遍历。

class Solution {
    public boolean makesquare(int[] nums) {
        //如果边少于4不能形成正方形
         if (null == nums || nums.length<4){
                return false;
            }
            int account = 0 ;
            for (int temp:nums) {
                account += temp;
            }
        //变数总和不是4的倍数不能成为正方形
            if (account%4!=0){
                return false;
            }
            //冒泡排序 降序
            for (int k = 0; k < nums.length - 1; k++) {
                for (int j = k + 1; j < nums.length; j++) {
                    if (nums[k] < nums[j]) {
                        int temp = nums[k];
                        nums[k] = nums[j];
                        nums[j] = temp;
                    }
                }
            }
            int sideLength = account/4;
            for (int i:nums) {
                //如果有一边大于边长。不能形成正方形
                if (i>sideLength){
                    return false;
                }
            }
        //四边
            int [] sides = new int[4];

            boolean search = search(0, sides, nums, sideLength);

            return search;
    }
    private static boolean search(int pos,int[] sides,int[] nums,int sideLength) {
            //遍历完成后判断每一边是否都相等
            if(pos >= nums.length){
                return  sides[0] == sideLength && sides[1] == sideLength
                        && sides[2] == sideLength && sides[3] == sideLength;
            }

            for (int i = 0; i < sides.length; i++) {
                if (sides[i]+nums[pos]>sideLength){
                    continue;
                }
                sides[i] += nums[pos];

            
                if (search(pos+1,sides,nums,sideLength)){
                    return true;
                };
                //回溯
                sides[i] = sides[i]-nums[pos];
            }



            return false;
        }
}

好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。

上期推文:

LeetCode1-460题汇总,希望对你有点帮助!

LeetCode刷题实战461:汉明距离

LeetCode刷题实战462:最少移动次数使数组元素相等 II

LeetCode刷题实战463:岛屿的周长

LeetCode刷题实战464:我能赢吗

LeetCode刷题实战465:最优账单平衡

LeetCode刷题实战466:统计重复个数

LeetCode刷题实战467:环绕字符串中唯一的子字符串

LeetCode刷题实战468:验证IP地址

LeetCode刷题实战469:凸多边形

LeetCode刷题实战470:用 Rand7() 实现 Rand10()

LeetCode刷题实战471:编码最短长度的字符串

LeetCode刷题实战472:连接词

LeetCode刷题实战473:火柴拼正方形_第1张图片

你可能感兴趣的:(算法,leetcode,java,面试,动态规划)