《程式設計師面試金典》上面的一道題目,leetcode也有這道題
返回某集合的所有非空子集。給定乙個int陣列a和陣列的大小int n,請返回a的所有非空子集。保證a的元素個數小於等於20,且元素互異。各子集內部從大到小排序,子集之間字典逆序排序,見樣例。
測試樣例:[123,456,789]
返回:
先按公升序排序,再列舉每個元素存在/不存在於集合之中。
class
subset
private
: vectorint>
> res;
void
helper
(vector<
int>
& arr, vector<
int>
& cur,
int n,
int k)
}else
}static
bool
cmp(
int x,
int y)
};
《程式設計師面試金典》上的方法,從包含最小個數元素的集合子集中迭代生成包含全部元素的集合子集。
舉例來說:的子集有, , , {}.
的子集有, , , {}∪ , , , {}.
可以看出是的子集可以通過的子集生成,左邊的粗體集合是的子集加上元素a得到的,右邊的集合是的子集。
class
subset
swap
(pa, pb);(
*pb)
= vectorint>
>()
;}return
*pa;
}private
:static
bool
cmp(
int x,
int y)
};
對於集合,可以用二進位制 2』111表示子集, 2』101來表示子集, 2』011來表示子集.
即i
ii-th位為1表示該位置的元素出現在集合中,0表示該位置的元素不出現。
演算法的思路,首先按公升序排序,再利用二進位制位來表示子集。 按(2n
−1
)(2^n - 1)
(2n−1)
到 1 的順序生成子集. 生成子集時候按a[n-1]到0的順序.
class
subset
--bit;
} res.
push_back
(cur);}
return res;
}private
:static
bool
cmp(
int x,
int y)
};
題目**於 leetcode 上的subsets ii
given a collection of integers that might containduplicates, nums, return all possible subsets (the power set).
note:the solution set must not contain duplicate subsets.
example:
input: [1,2,2]
output:
[ [2],
[1],
[1,2,2],
[2,2],
[1,2],
]
這裡主要針對重複的元素,如果元素重複了cnt次,我們應該選擇放入[0, cnt]次該元素來生成不同的集合。
class
solution
private
: vectorint>
> res;
vector<
int> cur;
void
helper
(vector<
int>
& nums,
int k)
int cnt =1;
while
(k+1
< nums.
size()
&& nums[k]
== nums[k+1]
)helper
(nums, k+1)
;for
(int i =
1; i <= cnt;
++i)
while
(cnt--)}
};
子集生成詳解
演算法入門經典上面有三種子集生成的演算法,我發現有些演算法有些需要注意的地方,寫出來防止被坑。第一種是增量構造法 include int cnt 0 void print int a,int cur,int n int main void 第二種是位向量法 include 列印出來的不是字典序順序 ...
子集生成模板
1 子集生成演算法 給定乙個集合,列舉所有可能的子集。2 為了簡單起見,討論的方法中沒有重複元素34 增量構造法 5 include6 include7 void print subset int n,int a,int cur 816 17intmain 18 1 位向量法2 構造乙個位向量b i...
子集生成演算法
劉汝佳書上的內容 下文提到的集合 其元素預設為0 n 1 n 個 意思就是一次選乙個 放到 裡 include include include include include include include include include include include include includ...