given a set of distinct integers, s, return all possible subsets.
note:
for example,
if s
=[1,2,3]
, a solution is:
[[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
]
本文總結了三種思路來求陣列的子集集合。前兩種思路雖然都基於遞迴,但是出發點略有不同;後一種思路基於位運算,但是對於原陣列的數量有限制。
1.基於dfs的遞迴
原陣列中每乙個元素在子集中有兩種狀態:要麼存在、要麼不存在。這樣構造子集的過程中每個元素就有兩種選擇方法:選擇、不選擇,因此可以構造一顆二叉樹來表示所有的選擇狀態:二叉樹中的第i+1層第0層無節點表示子集中加入或不加入第i個元素,左子樹表示加入,右子樹表示不加入。所有葉節點即為所求子集。因此可以採用dfs的遞迴思想求得所有葉節點。
**如下:
//s為原陣列,temp為當前子集,level為原陣列中的元素下標亦為二叉樹的層數,result為所求子集集合
void subsets(vector&s,vectortemp,int level,vector> &result)
//對於非葉子節點,不將當前元素加入到temp中
subsets(s,temp,level + 1,result);
//將元素加入到temp中
temp.push_back(s[level]);
subsets(s,temp,level + 1,result);
}
2.基於同質的遞迴
只要我們能找到比原問題規模小卻同質的問題,都可以用遞迴解決。比如要求的所有子集,可以先求的所有子集,的子集同時也是 的子集,然後我們把的所有子集都加上元素1後(注意排序),又得到同樣數量的子集, 它們也是的子集。這樣一來,我們就可以通過求的所有子集來求 的所有子集了。即為求1,2,3的子集,要先求2,3的子集,然後再把1加入到2,3的子集中去,典型的遞迴思路。**如下:
vector> subsets(vector&s,int idx,int n)
else
}return result;
}
3.位運算
求子集問題就是求組合問題。陣列中的n個數可以用n個二進位制位表示,當某一位為1表示選擇對應的數,為0表示不選擇對應的數。
vector> subsets(vector&s,int n)
idx++;
//判斷了這一位是否為1後要右移
j = j>>1;
}//判斷完了一種組合,加入到結果集中
result.push_back(temp);
}return result;
}
LeetCode Subsets 求陣列子集
given a set of distinct integers,s,return all possible subsets.note for example,if s 1,2,3 a solution is 3 1 2 1,2,3 1,3 2,3 1,2 分析 每個元素,都有放或者不放兩種選擇。深...
求陣列中和最大的子陣列
題目一 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每 個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n cpp view plain copy include stdio.h include conio.h 求一維陣列的最大連續子陣列元素之...
求陣列的所有子陣列的和的最大值 二維
組員 蔡容玉 張丹丹 題目 求陣列的所有子陣列的和的最大值 二維 把二維的問題化成一維的問題,首先我們知道某子矩陣的上,下邊界分別是a行和b行,接下來我們應該要確定左右邊界 把a行和b行之間的每一列看作是乙個整體,定義為 dc 1 dc 2 dc 3 dc m 把他們看作乙個元素並求出最大值 這樣就...