[Leetcode] Matchsticks to Square 火柴拼方形

Matchsticks to Square

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.python

Example 1: 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.ide

給定一個數組,其中每一個數字是火柴長度。求是否可以用且只用一次每一根火柴,經過首尾相連來拼出一個正方形。優化

深度優先搜索

思路

因爲正方形有四條邊,該搜索其實要知足四個目標才能算成功,即四條邊都用可以用火柴拼出來。想象此時咱們有個火柴隊列,咱們拿出一支火柴,先嚐試將它放入第一條邊上,若是第一條邊放得下,再拿出第二根火柴,嘗試繼續放在第一條邊上,若是此時發現已經放不下了,就試着把它放在第二條邊上,以此類推。細心的同窗可能會發現,若是第一根火柴在第一條邊上都放不進去的話,後面也都不用試了,由於每條邊長都同樣,一個放不進去的話其餘也放不進去。其實不僅是第一根火柴,因爲較長的火柴較不容易放入邊中,因此若是咱們先把較長的火柴放完再放較短的火柴,能幫助減小不少分叉的狀況。因此這裏一個優化的方法就是先將火柴排序,將長的放在前面。code

到這裏你可能會疑惑,爲何用完全部火柴就意味着四條邊都拼完了呢?由於咱們規定了邊長的目標爲總長除以4,而所火柴用完時總長已經肯定即爲邊長的4倍,那麼確定就是有四條邊被拼出來了。orm

代碼

class Solution:
    def makesquare(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        perimeter = sum(nums)
        if perimeter == 0 or perimeter % 4 != 0:
            return False
        sides = [perimeter // 4 for i in range(0, 4)]
        nums.sort(reverse=True) # 先試着拼較長的邊,有助於減小搜索分叉
        return self.findSolution(nums, sides, 0) # 從第一根開始嘗試拼出邊
    
    def findSolution(self, nums, sides, pos):
        if pos == len(nums):
            return True
        for index in range(0, 4): # 對於當前這個火柴,嘗試拼入上下左右四個邊
            if sides[index] >= nums[pos]:
                sides[index] -= nums[pos] # 用當前火柴拼第index個邊
                if self.findSolution(nums, sides, pos + 1): # 若是這個火柴被成功使用,就開始嘗試拼下一根火柴
                    return True
                sides[index] += nums[pos] # 把當前火柴從第index個邊中拿出來,好嘗試下一條邊
        return False
相關文章
相關標籤/搜索