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.
We want to use all matchsticks to form a square, i.e., partition them into 4 groups with equal sum. This is similar to the Partition to K Equal Sum Subsets problem. We use DFS to try all possible assignments of matchsticks to sides, pruning paths that exceed the target side length.
classSolution {
publicbooleanmakesquare(int[] nums) {
if (nums ==null|| nums.length< 4) returnfalse;
int sum = 0;
for (int num : nums) sum += num;
if (sum % 4 != 0) returnfalse;
return dfs(nums, newint[4], 0, sum / 4);
}
privatebooleandfs(int[] nums, int[] sides, int idx, int target) {
if (idx == nums.length) {
return sides[0]== target && sides[1]== target && sides[2]== target && sides[3]== target;
}
for (int i = 0; i < 4; i++) {
if (sides[i]+ nums[idx]> target) continue;
sides[i]+= nums[idx];
if (dfs(nums, sides, idx + 1, target)) returntrue;
sides[i]-= nums[idx];
}
returnfalse;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution:
defmakesquare(self, nums: list[int]) -> bool:
ifnot nums or len(nums) <4: returnFalse total = sum(nums)
if total %4!=0: returnFalse target = total //4 sides = [0] *4defdfs(idx):
if idx == len(nums):
return all(side == target for side in sides)
for i in range(4):
if sides[i] + nums[idx] > target: continue sides[i] += nums[idx]
if dfs(idx +1): returnTrue sides[i] -= nums[idx]
returnFalsereturn dfs(0)
Sorting the matchsticks in descending order allows us to try longer sticks first, which helps prune impossible branches earlier in DFS. This optimization significantly speeds up the search for a valid square partition.
import java.util.*;
classSolution {
publicbooleanmakesquare(int[] matchsticks) {
if (matchsticks ==null|| matchsticks.length< 4) returnfalse;
int sum = Arrays.stream(matchsticks).sum();
if (sum % 4 != 0) returnfalse;
Integer[] desc = Arrays.stream(matchsticks).boxed().toArray(Integer[]::new);
Arrays.sort(desc, Collections.reverseOrder());
int[] sticks = Arrays.stream(desc).mapToInt(Integer::intValue).toArray();
return dfs(sticks, newint[4], 0, sum / 4);
}
privatebooleandfs(int[] matchsticks, int[] sides, int idx, int target) {
if (idx == matchsticks.length) {
return sides[0]== target && sides[1]== target && sides[2]== target && sides[3]== target;
}
for (int i = 0; i < 4; i++) {
if (sides[i]+ matchsticks[idx]> target) continue;
sides[i]+= matchsticks[idx];
if (dfs(matchsticks, sides, idx + 1, target)) returntrue;
sides[i]-= matchsticks[idx];
}
returnfalse;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defmakesquare(self, matchsticks: list[int]) -> bool:
ifnot matchsticks or len(matchsticks) <4: returnFalse total = sum(matchsticks)
if total %4!=0: returnFalse target = total //4 matchsticks.sort(reverse=True)
sides = [0] *4defdfs(idx):
if idx == len(matchsticks):
return all(side == target for side in sides)
for i in range(4):
if sides[i] + matchsticks[idx] > target: continue sides[i] += matchsticks[idx]
if dfs(idx +1): returnTrue sides[i] -= matchsticks[idx]
returnFalsereturn dfs(0)