1. 程式人生 > >LeetCode--子集(Subsets)

LeetCode--子集(Subsets)

   給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

  示例:

輸入: nums = [1,2,3]輸出:

[

  [3],

  [1],

  [2],

  [1,2,3],

  [1,3],

  [2,3],

  [1,2],

  []

]

class Solution {

public:

vector<vector<int>> subsets(vector<int>& nums) {

vector<vector<int>> ret;

vector<int> t;

ret.push_back(t);//先插入一個空集

for (int length = 1; length <= nums.size(); length++)//子集陣列的長度,從1開始到和陣列長度相同

{

for (int start = 0; start < nums.size(); start++)//插入資料的起始位置

{

vector<int> temp;

if (start + length>nums.size() - 1)//防止訪問越界

break;

for (int go = start; go < start + length; go++)//從go開始走,到了子集陣列長度時就停

{

if (go>nums.size() - 1)

break;

temp.push_back(nums[go]);

}

ret.push_back(temp);



}

}

return ret;

}

};

 這是我最初寫的程式,在LeetCode上邊執行程式碼的時候以為沒錯誤就提交了

少了一種[1,3],仔細一想確實自己沒有解決這種情況,而且不知道怎麼才能去解決這種情況,當你有三個資料的時候這種情況只有一種,如果說當你有5個數據的時候,這種非連續子集就多了,124,125,13,14,15.......

class Solution {
public:
	vector<vector<int>> subsets(vector<int>& nums) {
		vector<vector<int>> ret(1);
		if (nums.size() == 0)
			return ret;
		for (int i = 0; i<nums.size(); i++)
		{
			int size = ret.size();
			for (int j = 0; j<size; j++)
			{
				ret.push_back(ret[j]);
				ret.back().push_back(nums[i]);
			}
		}
		return ret;
	}
};

   這是在網上看到的程式碼,不過一直沒明白是怎麼來實現的。假設我們要求的就是1,2,3,的子集

   我們跟著程式碼走一遍,進來先建立了一個二維vector,並且大小為1,這樣裡邊就有一個空的一維陣列了, 不需要再去定義一個空的插入進去。當剛進來的時候i=0;j=0;但是ret的size是1所以會進入第二個for迴圈,這時候把ret[0]又插入了一個進去,也就是這時候裡邊有兩個空陣列,然後通過ret.back來訪問我們第二個插入進去的空陣列,把nums[0]位置的資料插入了進去,這時候第二個for迴圈結束了,第一個結束了一層,此時裡邊已經有兩個一維陣列了一個空,一個是1.然後進入i++,又進入迴圈,這時候ret.size變成了2,上來先把ret[0]也就是空又插入了一遍,然後操作這個空陣列,把2插入了進去,這一層for迴圈就結束了,然後再插入一個ret[1]也就是隻有一個1的陣列插入了進來,然後操作這個新插的陣列,把2,插入了進去,這時候ret裡邊的資料是,空,1,2,12.然後開始第三層迴圈,這時候又把空插入了進來,然後把3放了進去,下一層迴圈插入1,把3放了進去,再之後插入2把3放了進去,之後再插入12,把3 放進去,這時候整個迴圈就結束了。

也就是當還沒有進入迴圈的時候ret裡邊只有一個空

當i=0的時候,ret裡邊有空,1

當i=1的時候,ret裡邊的所有資料都加了一個2,也就是包括,空,1,2,12,。

當i=2的時候,ret裡邊所有的資料都多了一個3,變成了,空,1,2,12,3,13,23,123.

這裡需要注意的是int size = ret.size();這句話不能少,如果說判斷條件用ret.size()的話,會進入死迴圈,因為ret的size每次在迴圈裡邊都會增加。