你將得到一個整數數組 matchsticks ,其中 matchsticks[i] 是第 i 個火柴棒的長度。你要用 所有的火柴棍 拼成一個正方形。你 不能折斷 任何一根火柴棒,但你可以把它們連在一起,而且每根火柴棒必須 使用一次 。
如果你能使這個正方形,則返回 true ,否則返回 false 。
示例 1:
輸入: matchsticks = [1,1,2,2,2]
輸出: true
解釋: 能拼成一個邊長為2的正方形,每邊兩根火柴。
示例 2:
輸入: matchsticks = [3,3,3,3,4]
輸出: false
解釋: 不能用所有火柴拼成一個正方形。
回溯方法:
首先計算所有火柴的總長度totalLen,如果 totalLen 不是 4 的倍數,那麼不可能拼成正方形,返回false。當 totalLen 是 4 的倍數時,每條邊的邊長為len = totalLen//4 ,用 edges 來記錄 44條邊已經放入的火柴總長度。對於第index 火柴,嘗試把它放入其中一條邊內且滿足放入後該邊的火柴總長度不超過len ,然後繼續枚舉第 index+1 根火柴的放置情況,如果所有火柴都已經被放置,那麼說明可以拼成正方形。
為了減少搜索量,需要對火柴長度從大到小進行排序。
class Solution:
def makesquare(self, matchsticks: List[int]) -> bool:
total = sum(matchsticks)
if total%4:
return False
matchsticks.sort(reverse=True)
edges = [0]*4
def dfs(idx):
if idx == len(matchsticks):
return True
for i in range(4):
# 判斷是否可以繼續添加火柴
if edges[i]+matchsticks[idx] <= (total//4):
# 如果兩個邊長不一樣,就繼續添加火柴
if i ==0 or edges[i] !=edges[i-1]:
edges[i] += matchsticks[idx]
if dfs(idx+1):
return True
# 回溯
edges[i] -= matchsticks[idx]
return False
return dfs(0)