leetcode 698 劃分為k個相等的子集

2021-10-24 17:23:41 字數 1857 閱讀 5782

給定乙個整數陣列 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...