已知数组A和其大小n,请返回A的所有非空子集。要求A中元素个数不大于20且互异。各子集内部从大到小排序,子集间字典逆序排序。
[123,456,789]
返回:{[789,456,123],[789,456],[789,123],[789],[456 123],[456],[123]}
首先按升序排序 再利用二进制位来表示子集 按((2^n) - 1)到 1 的顺序生成子集, 生成子集时候按(n-1)到0的顺序.
class Subset { public: vector<vector<int> > getSubsets(vector<int> A, int n) { // write code here sort(A.begin(), A.end()); int size = 1 << n; vector<vector<int> >subsets; for (int i = size - 1; i > 0; --i) { vector<int> subset; for (int j = n - 1; j >= 0; --j) { if ((i >> j) & 1) { subset.push_back(A[j]); } } subsets.push_back(subset); } return subsets; } };
public ArrayList<ArrayList<Integer>> getSubsets(int[] A, int n) { if(A==null||A.length==0) return new ArrayList<>(); Arrays.sort(A);// 数组A从小到大排序 return getSubsetsCore(A,n); } public ArrayList<ArrayList<Integer>> getSubsetsCore(int[] A,int n){ ArrayList<ArrayList<Integer>> outter = new ArrayList<ArrayList<Integer>>(); ArrayList<Integer> inner; if(n==1){// 循环终止条件 inner = new ArrayList<Integer>(); inner.add(A[0]); outter.add(inner); return outter; } ArrayList<ArrayList<Integer>> tmp = getSubsetsCore(A, n-1); int i,j; for (i = 0; i < tmp.size(); i++) {// 1. 在sets(n-1)的所有子集前边插入当前元素A[n-1]。 inner = new ArrayList<Integer>(); inner.add(A[n-1]); for (j = 0; j < tmp.get(i).size(); j++) { inner.add(tmp.get(i).get(j)); } outter.add(inner); } inner = new ArrayList<Integer>(); inner.add(A[n-1]); outter.add(inner);// 2. A[n-1]单独作为一个子集[A[n-1]]。 outter.addAll(tmp);// 3. sets(n-1)同时也应包含到sets(n)中。 return outter; }
# -*- coding:utf-8 -*- class Subset: # 返回二维[[],[],[]] def getSubsets(self, A, n): result = [[A[0]]] for i in range(1, n): tmp = result[:] for j in range(len(tmp)): tmp[j] = [A[i]] + tmp[j] result = tmp + [[A[i]]] + result return result
//总共有2^n-1种情况(n是数组个数),每种情况代表一个数,一个数的各位代表取或者不取。 public ArrayList<ArrayList<Integer>> getSubsets(int[] A, int n) { ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>(); Arrays.sort(A); int max = 1 << n; for (int k = max - 1; k >= 1; k--) { ArrayList<Integer> arr = new ArrayList<Integer>(); for (int i = k, index = 0; i > 0; i >>= 1, index++) { if ((i & 1) == 1) { arr.add(0, A[index]); } } list.add(arr); } return list; }
#if 1 bool Larger(int a, int b) { return a > b; } vector<vector<int> > getSubsets(vector<int> A, int n) { vector<vector<int> > allVec; if (A.size() == 0) return allVec; sort(A.begin(), A.end(), Larger); for (int i = 0; i < A.size(); i++) { vector<vector<int> > newV = allVec; allVec.clear(); for (auto v : newV) { auto vcopy = v; v.push_back(A[i]); allVec.push_back(v); allVec.push_back(vcopy); } vector<int> newv; // 加入null+A[i]单元素的vector newv.push_back(A[i]); allVec.push_back(newv); } return allVec; } #endif
class Subset { public: static bool comp1(const int&a, const int &b) { return a>b; } static bool comp2(const vector<int> &a, const vector<int> &b) { for (int i = 0; i<min(a.size(), b.size()); ++i){ if (a[i]>b[i]) return true; else if (a[i]<b[i]) return false; else continue; } if (a.size() > b.size())return true; else return false; } vector<vector<int> > getSubsets(vector<int> A, int n) { // write code here vector<vector<int> >result; vector<int> cur; bfs(result, cur, A, 0); for (int i = 0; i<result.size(); ++i) { sort(result[i].begin(), result[i].end(), comp1); } sort(result.begin(), result.end(), comp2); return result; } void bfs(vector<vector<int> >&result, vector<int> &cur, vector<int> A, int index) { if (!cur.empty()) { result.push_back(cur); } for (int i = index; i<A.size(); ++i) { cur.push_back(A[i]); bfs(result, cur, A, i + 1); cur.pop_back(); } } };
class Subset { public: vector<vector<int> > getSubsets(vector<int> A, int n) { // write code here bool *b = new bool[n]; memset(b, 0, sizeof(bool)*n); vector<vector<int> > result; myGetSubsets(A, n-1, n-1, b, result); return result; } void myGetSubsets(vector<int> &A, int start, int end, bool *b, vector<vector<int> > &result) { if(start < 0) { vector<int> r; for(int i = end; i >= 0; i--) if(b[i]) r.push_back(A[i]); if(!r.empty()) //去空集 result.push_back(r); return; } b[start] = true; //该元素被包含 myGetSubsets(A, start-1, end, b, result); b[start] = false; //该元素不被包含 myGetSubsets(A, start-1, end, b, result); return; } };
class Subset { public: vector<vector<int> > getSubsets(vector<int> A, int n) { // write code here vector<vector<int> > v; //从数组A的第一个元素开始 getSubsets(A, v, 0); //先对内部进行排序,从大到小 for(int i = 0; i < v.size(); ++i){ sort(v[i].begin(), v[i].end(), greater<int>()); } //再对外部进行排序,从大到小 sort(v.begin(), v.end(), greater<vector<int> >()); //弹出最后一个空元素数组 v.pop_back(); return v; } void getSubsets(vector<int> &A, vector<vector<int> > &v, int n){ if(A.size() == n){ return; } //如果是第一个元素,压入一个空数组和一个只有A[0]的数组 if(n == 0){ vector<int> temp1; vector<int> temp2; temp2.push_back(A[n]); v.push_back(temp1); v.push_back(temp2); } else{ int size = v.size()-1; for(int i = 0; i <= size; ++i){ vector<int> temp = v[i]; temp.push_back(A[n]); v.push_back(temp); } } getSubsets(A, v, n+1); } };
vector<vector<int> > getSubsets(vector<int> A, int n) { vector<vector<int>>ans; sort(A.begin(),A.end(),greater<int>()); vector<int>res; dfs(ans,res,A,0,n); sort(ans.begin(),ans.end(),greater<vector<int>>()); return ans; } void dfs(vector<vector<int>>&ans,vector<int>res,vector<int>A,int begin,int n){ if(begin == n)return; for(int i=begin;i<n;++i){ res.push_back(A[i]); ans.push_back(res); dfs(ans,res,A,i+1,n); res.pop_back(); } }
采用迭代相加的方法。
一开始初始化只有一个空集的一位数组元素的二维数组变量vector<vector<int> > vs(1),这个空变量是有用的,可以单独存放当前遍历到的给定数组元素。举个例子如下:
给定的数组从小到大排序:{1,2,3}
①{ }
②{ } + {1}
③{ }, {1} + {2} + {1, 2}
④{ }, {1}, {2}, {1, 2} + {3}, {1, 3}, {2, 3}, {1, 2, 3}
class Subset
{
public:
vector<vector<int> > getSubsets(vector<int> A, int n)
{
vector<vector<int> > vs(1);
for (int i = 0; i < A.size(); ++i)
{
//在当前二维数组的每个一位数组元素中插入当前的目标数组元素
//然后依次追加到vs中
int size = vs.size();
for (int j = 0; j < size; ++j)
{
vs.push_back(vs[j]);
vs.back().push_back(A[i]);
}
}
//先内部排序,从大到小
for(int i = 0;i < vs.size();i++)
sort(vs[i].begin(),vs[i].end(),greater<int>());
//总体排序,从大到小
sort(vs.begin(),vs.end(),greater<vector<int> >());
//弹出最后一个空的一位数组元素
vs.pop_back();
return vs;
}
};
# -*- coding:utf-8 -*- class Subset: # 返回二维[[],[],[]] def getSubsets(self, A, n): # write code here res = [] A.sort() self.dfs(A, res, []) return sorted(res, key=lambda c: "".join(map(str, c)), reverse=True) def dfs(self, arr, res, path): if path != sorted(path, reverse=True): return if path: res.append(path) if not arr: return for i in arr: a = arr[:] a.remove(i) self.dfs(a, res, path + [i])
public class Subset { public ArrayList<ArrayList<Integer>> getSubsets(int[] A, int n) { // write code here ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>(); int k = (1 << (n)) - 1; Arrays.sort(A); for (int i=0; i<n/2; i++){ //从大到小 int t = A[i]; A[i] = A[n-1-i]; A[n-1-i] = t; } while (k > 0){ ArrayList<Integer> list = new ArrayList<Integer>(); int j = 0; int z = 1 << (n-1); while (z > 0){ if ((z&k) > 0){ list.add(A[j]); } j++; z >>= 1; } lists.add(list); k--; } return lists; } }
// 因为这两个逆序,调了好久。。。 import java.util.*; public class Subset { public ArrayList<ArrayList<Integer>> getSubsets(int[] A, int n) { ArrayList<ArrayList<Integer>> allSubsets = new ArrayList<ArrayList<Integer>>(); int max = 1 << n; Arrays.sort(A); for (int k = 0; k < max; k++) { ArrayList<Integer> subset = convertIntToSet(k, A); if (subset.size() != 0) { allSubsets.add(0, subset); } } return allSubsets; } private ArrayList<Integer> convertIntToSet(int k, int[] A) { ArrayList<Integer> set = new ArrayList<Integer>(); int index = 0; for (int i = k; i > 0; i >>= 1) { if ((i & 1) == 1) { set.add(0, index); } index++; } return set; } }
// P0 = {} // P1 = 3 {} // P2 = 3,2 3 2 {} // P3 = 3,2,1 3,2 3,1 3 2,1 2 1 // 即每循环一轮,相当于在当前项前插入一项比当前项多出A[i]的项, 然后i+=2得到上一轮的下一项 using System.Collections.Generic; class Subset { public List<List<int>> getSubsets(int[] A, int n) { List<List<int>> list = new List<List<int>>(); if (n<0 || A==null) return list; System.Array.Sort(A); for (int i = 0; i < n; i++) { for (int j = 0; j <= list.Count; j+=2) { List<int> tmp = j < list.Count ? new List<int>(list[j]) : new List<int>(); tmp.Add(A[n-1-i]); list.Insert(j, tmp); } } return list; } }
//递归的方式,每一个元素只有取或者不取两种状况,假如取了,那么对剩下n-1个元素递归 class Subset { private: vector<vector<int> > res; vector<int> velem; void asisSub(vector<int> &A, int inx) { if(inx==A.size()) { if(!velem.empty()) res.push_back(velem); return; } asisSub(A, inx+1); velem.push_back(A[inx]); asisSub(A,inx+1); velem.pop_back(); } public: vector<vector<int> > getSubsets(vector<int> A, int n) { sort(A.rbegin(),A.rend()); asisSub(A,0); sort(res.rbegin(), res.rend()); return res; } };
vector<vector<int> > getSubsets(vector<int> A, int n) { // write code here vector<vector<int> > vec=helper(A,0); sort(vec.rbegin(), vec.rend());//排序 vec.pop_back();//弹出最后一个空的向量 return vec; } vector<vector<int> > helper(vector<int> A,int n)//辅助函数 { vector<vector<int> > vec; if(A.size()==n)//递归出口条件 { vec.push_back(vector<int>()); } else { vec=helper(A,n+1); int item=A[n]; vector<vector<int> > tmp; //vector<int>::iterator it=vec.begin(); for(int i=0;i<vec.size();i++)//自我拷贝,将该元素加入每一个向量中 { vector<int> newlist =vec[i]; newlist.push_back(item); tmp.push_back(newlist); } vec.insert(vec.end(),tmp.begin(),tmp.end());//从后面插入新的 } return vec; }