LeetCode Subsets && Subsets II

这是两个比较基础的搜索题(dfs),可能也叫做回溯法,个人觉得dfs一般都会有回溯,第一问比较简单,每次进入一个状态就把当前状态加入到ans中,如何只要在搜索过程中,记录当前的起点是第几个数,然后从该数往下搜索即可,注意保留现场,也就是push_back后还得pop_back,代码如下:
vector<vector<int> >ans;
vector<int>tmp;
void solve(int dep, vector<int> &S)
{
	ans.push_back(tmp);
	if (dep == S.size())
		return;
	int i;
	for (i = dep; i<S.size(); i++)
	{
		tmp.push_back(S[i]);
		solve(i+ 1, S);
		tmp.pop_back();
	}
	return;
}
class Solution {
public:
	vector<vector<int> > subsets(vector<int> &S) {
		int i;
		ans.clear();
		sort(S.begin(), S.end());
		tmp.clear();
		solve(0, S);
		return ans;
	}
};

第二位的关键就是如何去除重复的搜索,比如有1,2,2,3,那么其实第二个2和第三个2往下搜的结果都是一样的subset,只需要搜索他们其中的一个即可,那么可以这样判断,因为只有两个数相等时才会重复搜索,只要每次判断当前数是否和前一个数相等,如果相等,就不需要搜下去,因为前一次搜过了,不相等则继续往下搜,当然对于枚举的第一个数,他没有前一个数,所以他肯定要搜,并且前面搜索策略也保证了枚举的第一个数不可能是多个相同的数的非第一个(即第二个到最后一个),这其实是非常经典的剪枝。代码如下:

vector<vector<int> >ans;
vector<int>tmp;
void solve(int dep, vector<int> &S)
{
	ans.push_back(tmp);
	if (dep == S.size())
		return;
	int i;
	int cl = 1;
	for (i = dep; i<S.size(); i++)
	{
		if (i == dep)
		{
			tmp.push_back(S[i]);
			solve(i + 1, S);
			tmp.pop_back();
		}
		else if (i > dep&&S[i] != S[i - 1])
		{
			tmp.push_back(S[i]);
			solve(i + 1, S);
			tmp.pop_back();
		}
	}
	return;
}
class Solution {
public:
	vector<vector<int> > subsetsWithDup(vector<int> &S) {
		int i;
		ans.clear();
		sort(S.begin(), S.end());
		tmp.clear();
		solve(0, S);
		return ans;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值