給定乙個整數陣列 nums 和乙個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。
示例 1:
輸入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
輸出: true
說明: 有可能將其分成 4 個子集(5),(1,4),(2,3),(2,3)等於總和。
1 <= k <= len(nums) <= 16
0 < nums[i] < 10000
想象成有k
個空位置,遍歷陣列,對每個數字判斷當前的數字能不能放到當前的空位置裡面,如果能放進去,則遞迴,如果不能放進去,則回溯。
因為每個數字只能用一次,並且對乙個相同的空位置,對於a, b, c
這種的數字,當用了a
,再用b
時發現不可以,考慮b
的時候,不需要再考慮a
了,直接考慮b
後面的數字即可(這裡是剪枝)。這個空位置滿了,就換下個空位置,下個空位置就需要考慮全部的數字了。
在分數字的時候,其實可以優先考慮大的數,超過的部分盡早剪枝。所以可以預先對nums
排個序來剪枝
時間複雜度會比較高,最壞情況下複雜度會達到o(n
∗2n)
o(n * 2^n)
o(n∗2n
)(看官解得來的,但是為啥?)
class
solution
:def
canpartitionksubsets
(self, nums: list[
int]
, k:
int)
->
bool:if
sum(nums)
% k !=0or
max(nums)
>
sum(nums)
// k:
return
false
target =
sum(nums)
// k
visited_indexs =
[false]*
len(nums)
defhelper
(nums:
list
, cur_sum:
int, group_index:
int, begin_index:
int)
->
bool
:if group_index == k:
return
true
if cur_sum == target:
return helper(nums,
0, group_index +1,
0)if cur_sum > target:
return
false
for index in
range
(begin_index,
len(nums)):
if visited_indexs[index]
:continue
visited_indexs[index]
=true
if helper(nums, cur_sum + nums[index]
, group_index, index +1)
:return
true
visited_indexs[index]
=false
return
false
return helper(nums,0,
0,0)
LeetCode 698 劃分為k個相等的子集
給定乙個整數陣列 nums 和乙個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。回溯 因為每個元素都要用上,那取到和為target的一組值,就設定total為0重新取。遞迴終止條件是,當沒有值可取且target等於total。一旦找到這樣的集合,提前阻斷,一直返回true ...
LeetCode698 劃分為k個相等的子集
給定乙個整數陣列 nums 和乙個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。示例 1 輸入 nums 4,3,2,3,5,2,1 k 4 輸出 true 說明 有可能將其分成 4 個子集 5 1,4 2,3 2,3 等於總和。思路 1.計算出每個子集的和,為 sum s...
698 劃分為k個相等的子集 python
給定乙個整數陣列 nums 和乙個正整數 k,找出是否有可能把這個陣列分成 k 個非空子集,其總和都相等。示例 1 輸入 nums 4,3,2,3,5,2,1 k 4 輸出 true 說明 有可能將其分成 4 個子集 5 1,4 2,3 2,3 等於總和。注意 1 k len nums 16 0 n...