持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
力扣473. 火柴拼正方形
一、题目描述:
你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用所有的火柴棍拼成一个正方形。你 不能折断任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须使用一次 。
如果你能使这个正方形,则返回 true ,否则返回 false 。
示例 1:
输入: matchsticks = [1,1,2,2,2]
输出: true
解释: 能拼成一个边长为2的正方形,每边两根火柴。
示例 2:
输入: matchsticks = [3,3,3,3,4]
输出: false
解释: 不能用所有火柴拼成一个正方形。
提示:
1 <= matchsticks.length <= 15 1 <= matchsticks[i] <= 10^8
来源:力扣(LeetCode) 链接:leetcode.cn/problems/ma… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
-
这道题考察了什么思想?你的思路是什么?
这道题目我们需要计算火柴的长度之和,如果该值不是4的倍数,那么不能拼成正方形,返回false。如果是4的倍数,那么我们先计算四分之一的总长度,我们按从大至小放置火柴,对于第i根火柴,我们将其放入四条边之一,目的是不能让放入该火柴后,四条边都不能超过四分之一火柴总长度,以此类推,如若所有火柴都放置后,每条边都是四分之一火柴总长度,那么就能够形成正方形。
-
做题的时候是不是一次通过的,遇到了什么问题,需要注意什么细节?
不是一次通过的,判断条件时遇到了麻烦,大家一定要想清楚再做题啊。
-
有几种解法,哪种解法时间复杂度最低,哪种解法空间复杂度最低,最优解法是什么?其他人的题解是什么,谁的效率更好一些?用不同语言实现的话,哪个语言速度最快?
class Solution:
def makesquare(self, matchsticks: List[int]) -> bool:
totalLen = sum(matchsticks)
if totalLen % 4:
return False
tLen = totalLen // 4
dp = [-1] * (1 << len(matchsticks))
dp[0] = 0
for s in range(1, len(dp)):
for k, v in enumerate(matchsticks):
if s & (1 << k) == 0:
continue
s1 = s & ~(1 << k)
if dp[s1] >= 0 and dp[s1] + v <= tLen:
dp[s] = (dp[s1] + v) % tLen
break
return dp[-1] == 0
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/matchsticks-to-square/solution/huo-chai-pin-zheng-fang-xing-by-leetcode-szdp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public boolean makesquare(int[] matchsticks) {
int totalLen = Arrays.stream(matchsticks).sum();
if (totalLen % 4 != 0) {
return false;
}
int len = totalLen / 4, n = matchsticks.length;
int[] dp = new int[1 << n];
Arrays.fill(dp, -1);
dp[0] = 0;
for (int s = 1; s < (1 << n); s++) {
for (int k = 0; k < n; k++) {
if ((s & (1 << k)) == 0) {
continue;
}
int s1 = s & ~(1 << k);
if (dp[s1] >= 0 && dp[s1] + matchsticks[k] <= len) {
dp[s] = (dp[s1] + matchsticks[k]) % len;
break;
}
}
}
return dp[(1 << n) - 1] == 0;
}
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/matchsticks-to-square/solution/huo-chai-pin-zheng-fang-xing-by-leetcode-szdp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
三、AC 代码:
func makesquare(nums []int) bool {
n := len(nums)
if n < 4 || _sum(nums) % 4 != 0 {
return false
}
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j]
})
state := make([]bool, n)
return dfs(0, 0, _sum(nums) / 4, 0, nums, state)
}
func _sum(nums []int) (res int) {
for _, v := range nums {
res += v
}
return
}
func dfs(k, cursum, target, start int, nums []int, state []bool) bool {
if k == 4 {
return true
}
if cursum == target {
return dfs(k+1, 0, target, 0, nums, state)
}
for i:=start; i<len(nums); i++ {
if state[i]==false && nums[i] + cursum <= target {
state[i] = true
if dfs(k, nums[i] + cursum, target, i + 1, nums, state)==true {
return true
}
state[i] = false
}
}
return false
}
四、总结:
如果你还有更多的思考、分析、总结,通通都加上来吧~
473. 火柴拼正方形
判断条件时遇到了麻烦,大家一定要想清楚再做题啊。题目有些难度!