演算法 集合的子集

2022-05-22 16:39:14 字數 1763 閱讀 2325

給定乙個集合,輸出它的所有子集。

示例:給定集合{1,2,3},應該輸出:

增量構造法,每次選擇乙個元素放到集合中,每次操作的結果即是乙個子集。

遞迴操作,每次向當前集合中新增乙個比當前集合中最大的元素大1的數。

from

__future__

import

print_function

defprint_subset(n, lst, cur):

for i in

range(cur):

print(lst[i]+1, end=''

)

print

()

ifcur:

s = lst[cur - 1] + 1

else

: s =0

for i in

range(s, n):

lst[cur] =i

print_subset1(n, lst, cur+1)

構造位向量(可理解為構造乙個陣列),該向量中的每一位置可以取0值或者1值,0和1分別代表該位置上對應的值是否在集合中。如向量為[1, 0, 0, 1],其第1和4位上有1,所以該向量表示的集合為。

思路:如果需要用向量來表示集合,那麼需要保證向量的每一種變化能夠剛好覆蓋集合的每一種可能性。

對n求子集,構造長度為n的向量,每一位可以代表取或者不取該位置的值,共有2^n中可能。

from

__future__

import

print_function

defprint_subset(n, lst, cur):

if cur ==n:

for i in

range(n):

iflst[i]:

print(i+1, end=''

)

print

()

else

: lst[cur] =0

print_subset(n, lst, cur+1)

lst[cur] = 1print_subset(n, lst, cur+1)

我們可以使用二進位制法來表示子集。對於n求子集,其子集有2^n個(包括空集),比如n = 4,其有16個子集,這16個子集用二進位制可以表示成:

0->0000->{}

1->0001->

2->0010->

3->0011->

4->0100->

5->0101->

...15->1111->

思路:求n的子集,可以依次處理1到2^n - 1之間的每乙個數,每個數取出它二進位制表示中的1的位置,以此表示該數對應的集合。比如5,二進位制表示的後四位為0101,其在第1和第3位處有1,那麼,其代表的集合為。使用位運算中與(&)操作,可以方便的求出二進位制某位置上是否為1。

from

__future__

import

print_function

s = 1n = 4

while s < (1 << n): #

依次遍歷1到2^n - 1之間的每乙個數

for i in range(n): #

每乙個數使用&操作判斷該位置上是否有1,有列印或者儲存起來

if s & (1

)

print

() s += 1

集合的子集

題目描述 請編寫乙個方法,返回某集合的所有非空子集。給定乙個int陣列a和陣列的大小int n,請返回a的所有非空子集。保證a的元素個數小於等於20,且元素互異。各子集內部從大到小排序,子集之間字典逆序排序,見樣例。測試樣例 123,456,789 返回 假設有測試樣例 a,b,c 來看它是如何得到...

集合最大子集演算法 折衷演算法

我們直接來看乙個問題。給定乙個由n個整數組成的集合,其中n 40,每乙個整數都小於或等於 我們用例子來說明。例題1 輸入集合為 n 6,s 42 也就是從集合的6個元素中選擇適當的元素組成乙個子集,使得子集所有元素的和最大,並且該和小於或等於42。答案 該子集為,它的元素和為34 5 2 41,就是...

求解集合的子集

描述 求解集合的子集 思路 利用二進位制思想,如果在集合中某位數存在,那麼對應的二進位制的相應位數即為1。比如,集合對應的二進位制表示為 10110010 從右往左數 因此如果我們確定了乙個二進位制序列,對應的也就確定了乙個集合。此外,集合的運算可以利用 運算子,依次等價於集合的交集,並集和對稱差集...