代码随想录训练营day23|39. 组合总和,40.组合总和II,131.分割回文串

39.组合总和

题目
要求:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的同一个数字可以无限制重复被选取。
因为可以不停的用一个数字,所以在单层递归时不用传入i+1,继续传入i就好。

vector<vector<int>> result;
    vector<int> path;
    int sum=0;
    void backtracking(vector<int>& candidates,int target,int startindex){
        if(sum>target)
            return;
        if(sum==target){
            result.push_back(path);
            return;
        }
        for(int i=startindex;i<candidates.size();i++){
            path.push_back(candidates[i]);
            sum+=candidates[i];
            backtracking(candidates,target,i);
            //
            sum-=candidates[i];
            path.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        int startindex=0;
        sort(candidates.begin(),candidates.end());
        backtracking(candidates,target,startindex);
        return result;

    }

40.组合总和2

题目
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。

这题难在去重:

void backtracking(vector<int> candidates,int target,int startindex){
	if(sum>target)
		return;
	if(sum==target)
	{	
		result.push_back(path);
		return;
	}
	for(int i=startindex;i<candidates.size();i++){
		path.push_back(candidates[i]);
		sum+=candidates[i];
		backtracking(candidates,target,startindex);
		path.pop_back();
		sum-=candidates[i];
		while(i<candidates.size()-1&&candidates[i]==candidates[i+1])
			i++;//当然也可以写在开头
	//if(i>startidnex&&candidates[i]==candidates[i-1]);
		

	}

在这里插入图片描述
其实本题的去重方法和三数之和是一样的
三数之和

分割回文串

题目
切割问题和组合问题是一样的,如果不考虑回文的问题,但看怎么切割,那其实就是看
在一组数(1,2,3,4,5)中,能有多少种包含末尾数字的组合,12345,2345,245…
而这些数字就代表着子串数字的下标。
在这里插入图片描述

void cut(string s, int startindex){
	if(startindex==s.size())//到了字符串的最后
	{
		result.push_back(path);
		return;
	}
	for(int i=startindex;i<s.size();i++){
		string temp(s.begin()+startindex,s.begin()+i+1);
		//同层从左向右遍历,a->aa->aab;见上图;
		path.push(temp);
		cut(s,i+1);
		path.pop_back();
	}
}

但是由于还要判断是不是回文串,所以可以再写个函数来判断:

bool ishuiwen(string s){
	string temp=s;
	reverse(temp.begin(),temp.end());
	return temp==s;//将s翻转看是否相等
}

完整:

void cut(string s, int startindex){
	if(startindex==s.size())//到了字符串的最后
	{
		result.push_back(path);
		return;
	}
	for(int i=startindex;i<s.size();i++){
		string temp(s.begin()+startindex,s.begin()+i+1);
		//同层从左向右遍历,a->aa->aab;
		if(ishuiwen(temp)){
			path.push(temp);
			cut(s,i+1);
			path.pop_back();
		}
		//如果不是的话就往后切割,就可能会是回文,ab->aba;
	}
}
  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值