演算法 回溯 火柴拼正方形

2021-10-06 03:32:53 字數 2181 閱讀 1295

還記得童話《賣火柴的小女孩》嗎?現在,你知道小女孩有多少根火柴,請找出一種能使用所有火柴拼成乙個正方形的方法。不能折斷火柴,可以把火柴連線起來,並且每根火柴都要用到。

輸入為小女孩擁有火柴的數目,每根火柴用其長度表示。輸出即為是否能用所有的火柴拼成正方形。

示例 1:

輸入: [1,1,2,2,2]

輸出: true

解釋: 能拼成乙個邊長為2的正方形,每邊兩根火柴。

示例 2:

輸入: [3,3,3,3,4]

輸出: false

解釋: 不能用所有火柴拼成乙個正方形。

注意:給定的火柴長度和在 0 到 10^9之間。

火柴陣列的長度不超過15。

求所有火柴總長度,並計算邊長,如果不是整數則說明無法拼接成功

再迴圈一次,如果發現長度大於邊長的火柴返回失敗。同時將長度為0火柴排除,有效火柴放入edges準備遍歷

將有效火柴按長度逆序排序,因為我們拼接時優先滿足長的火柴,否則可能短火柴組成了邊,長火柴之間無法組合

使用回溯法分別組合需要組合的正方形邊,只要乙個組合不成功就失敗,否則返回成功。

class

solution

// 求所有火柴總長度

int total =0;

for(

int i =

0; i < nums.length; i++

)// 如果加出來的和不是4的整數倍,說明無法拼接成功

if(total %

4>0)

// 正方形邊長度

int edgelength = total /4;

// 待使用的有長度的火柴

list

edges =

newarraylist

<

>()

;// 將獨自組成邊的火柴記錄,長度為0火柴排除,有效火柴放入edges

for(

int i =

0; i < nums.length; i++

)else

}// 記錄是否使用

int[

] record =

newint

[edges.

size()

];// 待拼接的邊數

int targetedge =4;

// 將有效火柴按長度逆序排序,因為我們拼接時優先滿足長的火柴

// 否則可能短火柴組成了邊,長火柴之間無法組合

edges.

sort

((o1, o2)

->

else

if(o1.

equals

(o2)

)else})

;// 分別組合剩下需要組合的正方形邊

for(

int i =

0; i < targetedge; i++)}

// 全部能組合,返回成功

return

true;}

private

boolean

backtrack

(int edgelength, list

edges,

int start,

int tmpsum,

int[

] record)

if(tmpsum > edgelength)

// 遍歷選擇條件

for(

int i = start; i < edges.

size()

; i++

) tmpsum += edges.

get(i)

;// 選擇該火柴,將火柴標示為已使用

record[i]=1

;if(backtrack

(edgelength, edges, i +

1, tmpsum, record)

) tmpsum -= edges.

get(i)

;// 不選該火柴,將火柴下標標示為未使用

record[i]=0

;}// 遍歷完了都沒能組成邊,返回false

火柴拼正方形

還記得童話 賣火柴的小女孩 嗎?現在,你知道小女孩有多少根火柴,請找出一種能使用所有火柴拼成乙個正方形的方法。不能折斷火柴,可以把火柴連線起來,並且每根火柴都要用到。輸入為小女孩擁有火柴的數目,每根火柴用其長度表示。輸出即為是否能用所有的火柴拼成正方形。示例 1 輸入 1,1,2,2,2 輸出 tr...

473 火柴拼正方形

還記得童話 賣火柴的小女孩 嗎?現在,你知道小女孩有多少根火柴,請找出一種能使用所有火柴拼成乙個正方形的方法。不能折斷火柴,可以把火柴連線起來,並且每根火柴都要用到。輸入為小女孩擁有火柴的數目,每根火柴用其長度表示。輸出即為是否能用所有的火柴拼成正方形。示例 1 輸入 1,1,2,2,2 輸出 tr...

LeetCode 473 火柴拼正方形

還記得童話 賣火柴的小女孩 嗎?現在,你知道小女孩有多少根火柴,請找出一種能使用所有火柴拼成乙個正方形的方法。不能折斷火柴,可以把火柴連線起來,並且每根火柴都要用到。輸入為小女孩擁有火柴的數目,每根火柴用其長度表示。輸出即為是否能用所有的火柴拼成正方形 我看到題目,很快就想到了等分k份陣列這道題目....