1. 程式人生 > >子集生成之增量構造法(允許有重複元素)

子集生成之增量構造法(允許有重複元素)

假設集合S中有n個元素,它的子集的元素個數可以為1至n個,這個問題等價於有n個桶,按順序擺好並編號0~n-1,然後我們依次走到這n個桶面前,此時我們可以決定不放元素,或者放一個元素,因為集合是無序的(集合{1,2,3}和{2,1,3}相同),所以我們可以事先將S中的元素排序,這樣我們走到編號為step的桶前只需考慮是否放入一個S中索引大於等於step的元素,如果S中索引大於等於step的元素當中有重複的,我們只放入一次;每次走到下一個桶後我們把前面的桶所形成的子集儲存下來,這樣就能得到S的全部子集。具體程式碼如下:

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
	vector<vector<int> > subsetsWithDup(vector<int> &S) {
		vector<vector<int> > result;
		vector<int> singleResult;
		sort(S.begin(),S.end());
		subsetsWithDup(result,singleResult,S,0);
		return result;
	}
	void subsetsWithDup(vector<vector<int> > &result,vector<int> &singleResult,vector<int> &S,int step)
	{
		result.push_back(singleResult); //儲存之前已經走過的桶形成的子集
		for(int i=step;i<S.size();++i)
		{
			if(i!=step && S[i]==S[i-1])  //保證重複的元素只選一個
				continue;
			singleResult.push_back(S[i]);
			subsetsWithDup(result,singleResult,S,i+1);
			singleResult.pop_back();
		}
	}
};
int main()
{
	int inputArray[]={1,2,2,3};
	vector<int> inputVec(inputArray,inputArray+4);
	vector<vector<int>> result;
	vector<int> singleResult;
	Solution sln;
	result=sln.subsetsWithDup(inputVec);
	for (int i=0;i<result.size();++i)
	{
		for (int j=0;j<result[i].size();++j)
		{
			cout<<result[i][j]<<" ";
		}
		cout<<endl;
	}
}
當集合S為{1,2,2,3}時,程式執行結果如下:結果包括了一個空集哦