LeetCode 1681 最小不相容性

2021-10-11 17:34:18 字數 2050 閱讀 2605

題目鏈結

給你乙個整數陣列 nums​​​ 和乙個整數 k 。你需要將這個陣列劃分到 k 個相同大小的子集中,使得同乙個子集裡面沒有兩個相同的元素。

乙個子集的 不相容性 是該子集裡面最大值和最小值的差。

請你返回將陣列分成 k 個子集後,各子集 不相容性 的 和 的 最小值 ,如果無法分成分成 k 個子集,返回 -1 。

子集的定義是陣列中一些數字的集合,對數字順序沒有要求。

輸入:nums =

[1,2,1,4], k = 2

輸出:4

解釋:最優的分配是 [1,2] 和 [1,4] 。

不相容性和為 (2-1) + (4-1)

= 4 。

注意到 [1,1] 和 [2,4] 可以得到更小的和,但是第乙個集合有 2 個相同的元素,所以不可行。

輸入:nums =

[6,3,8,1,3,1,2,2], k = 4

輸出:6

解釋:最優的子集分配為 [1,2],[2,3],[6,8] 和 [1,3] 。

不相容性和為 (2-1) + (3-2) + (8-6) + (3-1)

= 6 。

輸入:nums =

[5,3,3,6,3,3], k = 3

輸出:-1

解釋:沒辦法將這些數字分配到 3 個子集且滿足每個子集裡沒有相同數字。

比賽時只想到了爆搜,完全忽視了 dp,結果最後也沒搞出來,後來發現這題是狀壓 dp,好像很久沒碰到了?,的確比較難想~

狀壓 dp,顧名思義就是壓縮狀態,暴力判斷的複雜度最大為 16

!16!

16!,而狀壓 dp 的最壞複雜度為 2

162^

216,顯然後者是可取的。我們用乙個二進位制數 x

xx 表示陣列選擇的狀態,對二進位制的每一位,1

11 表示選中,0

00 表示不選,首先可以用 val

ue[x

]value[x]

value[

x]記錄每個合法二進位制數的不相容性,何為合法二進位制數?顯然有且僅有 num

s.si

ze()

k\frac

knums.

size

()​ 個 1

11,且這些選中的數不重複,即為合法。在算完不相容性後,很容易得到狀態轉移方程,用 dp[

i]

dp[i]

dp[i

] 表示某乙個二進位制狀態的最小不相容性,則有:

d p[

i]=m

in(d

p[i]

,dp[

i⊕j]

+val

ue[j

]),j

⊂i

dp[i]=min(dp[i],dp[i\oplus j]+value[j]),j\subset i

dp[i]=

min(

dp[i

],dp

[i⊕j

]+va

lue[

j]),

j⊂i解釋一下,當 j

jj 為 i

ii 的子集時,i

ii 的最小不相容性即為去掉 j

jj 的狀態(i⊕j

i\oplus j

i⊕j) 的最小不相容性加上狀態 j

jj 的不相容性,最後全選的狀態 m=2

n−

1m=2^n-1

m=2n−1

的 dp[m

]dp[m]

dp[m

] 即為最終答案,ac**如下:

class

solution

int p=0;

for(

int j=

1;j<=n;j++)}

if(!p)}

} dp[0]

=0;for

(int i=

0;i}}

return dp[m-1]

;}};

leetcode 使結果不超過閾值的最小除數

給你乙個整數陣列 nums 和乙個正整數 threshold 你需要選擇乙個正整數作為除數,然後將陣列裡每個數都除以它,並對除法結果求和。請你找出能夠使上述結果小於等於閾值 threshold 的除數中最小的那個。每個數除以除數後都向上取整,比方說 7 3 3 10 2 5 題目保證一定有解 示例 ...

Leetcode 最小K個數

思路 基於快排改進 選取arr 0 作為基準值,tmp arr 0 排序後,返回tmp的下標index 此時,arr index 左側的值都小於tmp,右側的值都大於tmp。如果k index,那麼從起始點0到下標index 1的值就為最小的k個數,如果k index,說明k個數在區間 0,inde...

leetcode 最小高度樹

給定乙個有序整數陣列,元素各不相同且按公升序排列,編寫乙個演算法,建立一棵高度最小的二叉搜尋樹。由於陣列已經是有序陣列,所以構建二叉搜尋樹並不難,基於二叉樹的特性,我們將陣列劃分為兩部分,遞迴構建其左右子樹即可.對於題目中要求的高度最小,我們知道一棵平衡樹是高度最小的二叉樹.因此我們每次切分應當保證...