生活随笔
收集整理的這篇文章主要介紹了
子集(TX)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
思路
求子集問題和回溯算法:求組合問題!和回溯算法:分割問題!又不一樣了。
如果把 子集問題、組合問題、分割問題都抽象為一棵樹的話,「那么組合問題和分割問題都是收集樹的葉子節點,而子集問題是找樹的所有節點!」
其實子集也是一種組合問題,因為它的集合是無序的(順序怎樣都沒關系),子集{1,2} 和 子集{2,1}是一樣的。
「那么既然是無序,取過的元素不會重復取,寫回溯算法的時候,for就要從startIndex開始,而不是從0開始!」
從圖中紅線部分,可以看出「遍歷這個樹的時候,把所有節點都記錄下來,就是要求的子集集合」。
class Solution {
public:vector
<vector
<int>> res
;vector
<int> path
;void backtracking(vector
<int>& nums
,int startIndex
){if(startIndex
>=nums
.size()){return;}for(int ii
=startIndex
;ii
<nums
.size();ii
++){path
.push_back(nums
[ii
]);res
.push_back(path
);backtracking(nums
,ii
+1);path
.pop_back();}}vector
<vector
<int>> subsets(vector
<int>& nums
) {backtracking(nums
,0);res
.push_back({});return res
;}
};
class Solution {
private:vector
<vector
<int>> result
;vector
<int> path
;void backtracking(vector
<int>& nums
, int startIndex
) {result
.push_back(path
); if (startIndex
>= nums
.size()) { return;}for (int i
= startIndex
; i
< nums
.size(); i
++) {path
.push_back(nums
[i
]);backtracking(nums
, i
+ 1);path
.pop_back();}}
public:vector
<vector
<int>> subsets(vector
<int>& nums
) {result
.clear();path
.clear();backtracking(nums
, 0);return result
;}
};
class Solution {
public:vector
<vector
<int>> res
;vector
<int> path
;void backtracking(vector
<int>& nums
,int startIndex
,vector
<bool>& used
){res
.push_back(path
);if(startIndex
>=nums
.size()){return;}for(int ii
=startIndex
;ii
<nums
.size();ii
++){if(ii
>0&&nums
[ii
-1]==nums
[ii
]&&used
[ii
-1]==false) continue;path
.push_back(nums
[ii
]);used
[ii
]=true;backtracking(nums
,ii
+1,used
);path
.pop_back();used
[ii
]=false;}}vector
<vector
<int>> subsetsWithDup(vector
<int>& nums
) {vector
<bool> used(nums
.size(),false);sort(nums
.begin(),nums
.end());backtracking(nums
,0,used
);return res
;}
};
總結
以上是生活随笔為你收集整理的子集(TX)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。