遞迴 LeetCode473 火柴拼正方形

2021-10-24 04:55:51 字數 2150 閱讀 9621

回溯法的求解過程實質上是乙個先序遍歷一棵狀態樹的過程,只是這棵樹不是遍歷前預先建立的,而是隱含在遍歷的過程中。

遞迴題的解法:首先把題目的決策樹畫出來,樹的層就是for迴圈,樹的深度就是要遞迴的引數i。畫出決策樹後,找規律,進行剪枝。

e.g.輸入【1, 1, 2, 2, 2】

放小球問題,總共四個盒子,每個數從大到小依次網盒子裡放,放滿則放到下乙個盒子

首先將所有的數進行從大到小排序,先放大的,後放小的。

樹層為四個盒子,樹的深度為每個數。

// 正方形的四條邊恰好相當於四個盒子,然後依次向每個盒子裡面放入給定小球,如果乙個盒子放滿了則放到下乙個盒子裡。

bool

addstick

(int i,

const std::vector<

int>

& nums,

int target_side_len,

int side_sums[4]

)return

false;}

for(

int j =

0; j <4;

++j)

side_sums[j]

+= nums[i]

;// 在當前的盒子放入下乙個數if(

addstick

(i +

1, nums, target_side_len, side_sums)

)// 嘗試完這個數恢復之前的狀態, 然後放入下乙個盒子。

side_sums[j]

-= nums[i];}

return

false;}

bool

makesquare1

(std::vector<

int> nums)

// 對於遞迴在題目中提前找到剪枝條件十分重要。

int sum = std::

accumulate

(nums.

begin()

, nums.

end(),

0);if

(sum %4!=

0)int side_length = sum /4;

for(

int num : nums)

}// 由大到小排序,該條件至關重要。

// 由大到小排序後,可以極大地減少遞迴的次數。

std::

sort

(nums.

begin()

, nums.

end(

), std::greater<

int>()

);int side_sums[4]

=;return

addstick(0

, nums, side_length, side_sums);}

intmain()

)<< std::endl;

std::cout <<

makesquare1()

<< std::endl;

std::cout <<

makesquare1()

<< std::endl;

std::cout <<

makesquare1()

<< std::endl;

return0;

}

LeetCode 473 火柴拼正方形

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

LeetCode 473 火柴拼正方形 C

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

473 火柴拼正方形

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