[LeetCode] Challenge log 473

473. Matchsticks to Square

Analysis: Similar to 39, 40. But it needs 4 combinations that has equal sum.

Alg1:

Hence one natural approach it to find one target at a time, mark the used number and then recursively find the second one, until the fouth is found.

Alg2:

Second alg is to sort the array in decending order, then find a combination whose sum equals to target, we know that this must be one of the conbination in the answer (no proof yet), hence we can eliminate all other possible first combination and go on to fin the sencond. Same as above, once another combination is found, it must be the “true” second combination, and so on.


Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match girl has, please find out a way you can make one square by using up all those matchsticks. You should not break any stick, but you can link them up, and each matchstick must be used exactly one time.

Your input will be several matchsticks the girl has, represented with their stick length. Your output will either be true or false, to represent whether you could make one square using all the matchsticks the little match girl has.

Example 1:

1
2
3
4
Input: [1,1,2,2,2]
Output: true

Explanation: You can form a square with length 2, one side of the square came two sticks with length 1.

Example 2:

1
2
3
4
Input: [3,3,3,3,4]
Output: false

Explanation: You cannot find a way to form a square with all the matchsticks.

Note:

  1. The length sum of the given matchsticks is in the range of 0 to 10^9.
  2. The length of the given matchstick array will not exceed 15.

Soulution:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Alg1
class Solution:
def makesquare(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
if nums == []: return False

s = sum(nums)
if s % 4 != 0: return False

side = s // 4
n = 4
nums = sorted(nums, reverse = True)

def dfs(target, nums, last, count):

# check if a combination is found
if target == 0:
count += 1
print(nums, count,target)
# check if we have found 4 combination, go recurring if have not
if count == 4:
return True
else:
if dfs(side, nums, 0, count): return True
return False

# find a unused valid number to be in the combination. mark it is used.
for i in range(last, len(nums)):
if not nums[i]: continue
if nums[i] > target: continue
temp = nums[i]
nums[i] = None
if dfs(target-temp, nums, i, count): return True
nums[i] = temp

if dfs(side, nums, 0, 0):
return True
else:
return False
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# Alg2
class Solution:
def makesquare(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
# if empty or not divided by 4
if nums == []: return False
s = sum(nums)
if s % 4 != 0: return False

def dfs(target, nums, last):
# if found
if target == 0:
return True

# mark the used when looking for solution
for i in range(last, len(nums)):
if not nums[i]: continue
if nums[i] > target: continue
temp = nums[i]
nums[i] = None
if dfs(target-temp, nums, i): return True
nums[i] = temp

return False

# sort the array in deccending order, so that the first found set must be the "true set"!
side = s // 4
nums = sorted(nums, reverse = True)

# dfs it 4 times, return true if all succeed.
res = True
for i in range(4):
res = res and dfs(side, nums, 0)
return res
0%